1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
// -*-c++-*-
// fixg2sxd - a utility to convert fig to sxd format
// Copyright (C) 2003-2022 Alexander Bürger, acfb@users.sourceforge.net
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "xfigobjects.h"
#include "xmlwrite.h"
#include "misc.h"
#include <iomanip>
// TODO: non-ps fonts?
// TODO: symbol font does not show anything
istream& Text::read( istream& figfile )
{
int unused_pen_style; // (enumeration , not used)
TextStyle ts;
figfile >> ts.justification >> ts.color >> depth >> unused_pen_style
>> ts.font >> ts.font_size >> angle >> ts.font_flags
>> height >> length >> x >> y;
ts.check();
textstyle = textstyles.insert( ts ).first;
textstyle->stylenumber();
// read the string characterwise
char ch;
figfile.get( ch ); // skip initial space
while( true ) {
figfile.get( ch );
if( ch == '\\' ) {
figfile.get( ch );
if( ch != '\\' ) {
int ch2 = figfile.get();
int ch3 = figfile.get();
int value = 64*(ch-'0') + 8*(ch2-'0') + (ch3-'0');
if( value == 1 )
break;
ch = char(value);
}
}
text += ch;
}
return figfile;
}
ostream& Text::write( ostream& out )
{
// --------- use line to position text -------------
// extracted from creating text with OOo draw, printing as ps,
// converting to fig with pstoedit and making linear regression;
// finally for small fonts, a correction was done
const float length = 50;
const float fs = textstyle->font_size;
const float off = -( 0.23 + 6.63*fs );
if( fabs(angle - M_PI) < 1e-4 ) {
angle = 179.8*M_PI/180;
static bool warn_angle = false;
if( !warn_angle ) {
cerr << "Warning: all text angles 180° are replaced by "<<angle*180/M_PI<<"°" << endl;
warn_angle = true;
}
}
float justify = (textstyle->justification==0) ? 0 :
((textstyle->justification==1) ? -length/2.0 : -length);
float x1 = x + sin(angle)*off + cos(angle)*justify;
float y1 = y + cos(angle)*off - sin(angle)*justify;
float x2 = x1 + cos(angle)*length;
float y2 = y1 - sin(angle)*length;
Node line("draw:line");
line["draw:layer"] << "layout";
line["draw:z-index"] << depth2z(depth);
line["draw:style-name"] << textstyle->stylenumber();
line["svg:x1"] << tr(x1) << "cm";
line["svg:y1"] << tr(y1) << "cm";
line["svg:x2"] << tr(x2) << "cm";
line["svg:y2"] << tr(y2) << "cm";
Node& textp=line.subnode("text:p");
if( textstyle->font/4 == 5 )
textp["text:style-name"] << "P1";
ostringstream& txt = textp.text().t();
unsigned char last=0;
for( unsigned i=0; i<text.length(); ++i ) {
unsigned char ch = text[i];
if( (ch>' ' && ch < 128) || (ch==' '&&last!=' ') ) {
switch( ch ) {
case '<': txt << "<"; break;
case '>': txt << ">"; break;
case '\'': txt << "'"; break;
case '\"': txt << """; break;
case '&': txt << "&"; break;
default:
txt << text[i];
}
} else if( ch == '\n' ) { // line break
txt << "<text:line-break/>";
} else if( ch == ' ' ) { // multiple spaces
unsigned secondspace = i;
while( i<text.length() && text[i] == ' ' )
++i;
txt << "<text:s text:c=\"" << ( i-secondspace ) << "\"/>";
if( text[i] != ' ' )
--i;
} else if( ch>=' ') {
txt << "&#" << setw(4) << setfill('0') << unsigned(ch) << ";";
}
last = ch;
}
return out << line;
}
|