1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svtools.hxx" 26 27 #include <rtl/math.h> 28 #include <tools/config.hxx> 29 #include <svtools/filter.hxx> 30 #include "sgffilt.hxx" 31 #include "sgfbram.hxx" 32 #include "sgvmain.hxx" 33 // #include "Debug.c" 34 35 extern SgfFontLst* pSgfFonts; 36 37 #ifndef abs 38 #define abs(x) ((x)<0 ? -(x) : (x)) 39 #endif 40 41 42 //////////////////////////////////////////////////////////////////////////////////////////////////// 43 // 44 // Einschraenkungen: Schatten nur grau, 2D und mit fixem Abstand. 45 // 46 // 47 // 48 // 49 //////////////////////////////////////////////////////////////////////////////////////////////////// 50 51 ///////////////////////////////////////////////////////////////////////////////// 52 ///////////////////////////////////////////////////////////////////////////////// 53 ///////////////////////////////////////////////////////////////////////////////// 54 // AbsBase.Pas 55 56 // die folgenden Werte sind in % vom maximalen Schriftgrad der Zeile */ 57 #define UndlSpace 5 /* Untersteichungsabstand von der Baseline */ 58 #define UndlWidth 6 /* Untersteichungsdicke */ 59 #define UndlSpac2 7 /* Zwischenraum bei doppelter Unterstreichung */ 60 #define StrkSpace 25 /* Abstand der Durchstreichlinie von der Baseline*/ 61 #define StrkWidth 5 /* Durchstreichungsliniendicke */ 62 #define StrkSpac2 7 /* Zwischenraum bei doppelter Durchstreichung */ 63 #define OutlWidth 2 /* Strichstaerke ist 2% vom Schriftgrad */ 64 65 // vvv Sonderzeichen im TextBuffer vvv 66 #define TextEnd 0 /* ^@ Ende der Zeichenkette */ 67 #define HardSpace 6 /* ^F Hartspace (wird nicht umbrochen) ,' ' */ 68 #define GrafText 7 /* ^G Im Text eingebundene Grafik (future) */ 69 #define Tabulator 9 /* ^I Tabulatorzeichen, Pfeil */ 70 #define LineFeed 10 /* ^J Neue Zeile */ 71 #define SoftTrennK 11 /* ^K Zeichen fuer k-c-Austausch bei Trennung, 'k' */ 72 #define AbsatzEnd 13 /* ^M Neuer Absatz =CR */ 73 #define HardTrenn 16 /* ^P Hartes Trennzeichen (wird nicht umbrochen), '-' */ 74 #define SoftTrennAdd 19 /* ^S Zusatz-Zeichen Trennung von z.b."Schiff-fahrt" */ 75 #define Paragraf 21 /* ^U Zeichen welches fuer Paragraf-Zeichen */ 76 #define Escape 27 /* ^[ Escapesequenz einleiten */ 77 #define SoftTrenn 31 /* ^_ Weiches Trennzeichen, '-' nur Zeilenende */ 78 #define MaxEscValLen 8 79 #define MaxEscLen (MaxEscValLen+3) 80 81 //============================================================================== 82 // Escapesequenzen: [Esc]<Ident><Value>[Esc] also mind. 4 Char 83 // Max. Laenge von Value soll sein: 8 Char (7+Vorzeichen). Demnach max. Laenge 84 // einer Escapesequenz: 11 Char. 85 // Identifer: 86 87 #define EscFont 'F' /* FontID, z.B. 92500 fuer CG Times */ 88 #define EscGrad 'G' /* Schriftgrad 1..255 fuer <<Pt-127<<Pt */ 89 #define EscBreit 'B' /* Breite 1..255% des Schriftgrades */ 90 #define EscKaptS 'K' /* Kapitaelchengroesse 1..255% des Schriftgrades */ 91 #define EscLFeed 'L' /* Zeilenabstand 1..32767% vom max. Schriftgrad der Zeile */ 92 // oder 1..32767 fuer 1..16383<<Pt absolut (Wenn Bit 15=1) 93 #define EscSlant 'S' /* Kursiv(Winkel) 1..8999 fuer 0.01deg..89.99deg */ 94 #define EscVPos 'V' /* Zeichen Vertikal-Position 1..255 fuer <<Pt..127<<Pt */ 95 #define EscZAbst 'Z' /* Zeichenabstand -128..127% */ 96 #define EscHJust 'A' /* H-Justify Absatz: Links, Zentr, Rechts, Block, Austreibend, Gesperrt (0..5)*/ 97 98 #define EscFarbe 'C' /* Farbe 0..7 */ 99 #define EscBFarb 'U' /* BackFarbe 0..7 */ 100 #define EscInts 'I' /* Farbintensitaet 0..100% */ 101 #define EscMustr 'M' /* Muster 0..? inkl. Transp... */ 102 #define EscMFarb 'O' /* Musterfarbe 0..7 */ 103 #define EscMBFrb 'P' /* 2. Musterfarbe 0..7 */ 104 #define EscMInts 'W' /* Musterintensitaet 0..7 */ 105 106 #define EscSMstr 'E' /* Schattenmuster 0..? inkl. Transp... */ 107 #define EscSFarb 'R' /* Schattenfarbe 0..7 */ 108 #define EscSBFrb 'T' /* 2. Schattenfarbe 0..7 */ 109 #define EscSInts 'Q' /* Schattenintensitaet 0..7 */ 110 111 #define EscSXDst 'X' /* Schattenversatz X 0..100% */ 112 #define EscSYDst 'Y' /* Schattenversatz Y 0..100% */ 113 #define EscSDist 'D' /* Schattenversatz X-Y 0..100% */ 114 115 #define EscBold 'f' /* Fett */ 116 #define EscLSlnt 'l' /* LKursiv */ 117 #define EscRSlnt 'r' /* RKursiv */ 118 #define EscUndln 'u' /* Unterstrichen */ 119 #define EscDbUnd 'p' /* doppelt Unterstrichen */ 120 #define EscKaptF 'k' /* Kapitaelchenflag */ 121 #define EscStrik 'd' /* Durchgestrichen */ 122 #define EscDbStk 'e' /* doppelt Durchgestrichen */ 123 #define EscSupSc 'h' /* Hochgestellt */ 124 #define EscSubSc 't' /* Tiefgestellt */ 125 #define Esc2DShd 's' /* 2D-Schatten */ 126 #define Esc3DShd 'j' /* 3D-Schatten */ 127 #define Esc4DShd 'i' /* 4D-Schatten */ 128 #define EscEbShd 'b' /* Embossed */ 129 130 // AllEscIdent =[EscFont, EscGrad, EscBreit,EscKaptS,EscLFeed,EscSlant,EscVPos, EscZAbst,EscHJust, 131 // EscFarbe,EscBFarb,EscInts, EscMustr,EscMFarb,EscMBFrb,EscMInts, 132 // EscSMstr,EscSFarb,EscSBFrb,EscSInts,EscSXDst,EscSYDst,EscSDist, 133 // EscBold, EscLSlnt,EscRSlnt,EscUndln,EscDbUnd,EscKaptF,EscStrik,EscDbStk, 134 // EscSupSc,EscSubSc,Esc2DShd,Esc3DShd,Esc4DShd]; 135 // Justify muss spaetestens am Anfang des Absatzes stehen 136 #define EscSet '' /* Flag setzen */ 137 #define EscReset '' /* Flag loeschen */ 138 #define EscDeflt '\x11' /* Flag auf default setzen */ 139 #define EscToggl '' /* Flag Toggeln */ 140 #define EscRelat '%' 141 #define EscNoFlg 0 142 #define EscNoVal -2147483647 /* -MaxLongInt */ 143 //============================================================================== 144 #define NoTrenn 0xFFFF /* Wert fuer Parameter 'Rest' von GetTextChar(), wenn auf keinen Fall getrennt werden soll */ 145 #define DoTrenn 0xFFFE /* Wert fuer Parameter 'Rest' von GetTextChar(), wenn getrennt werden soll */ 146 147 #define MaxLineChars 1024 148 149 #define ChrXPosArrSize (MaxLineChars+1+1) /* 2k - Beginnt mit 0 im gegensatz zu StarDraw */ 150 #define CharLineSize (MaxLineChars+1+1) 151 #define EscStr (UCHAR[MaxEscLen+1]); 152 153 #define MinChar 32 154 #define MaxChar 255 155 156 157 //============================================================================== 158 159 #define DefaultCharWidth 4800 160 #define GradDiv 2 161 #define CharTopToBase 100 /* wegen Apostrophe und Umlaute mehr als 75% */ 162 #define CharTopToBtm 120 /* Zeilenhoehe ist groesser als Schriftgrad */ 163 // bei Avanti-Bold 'ue' eigentlich sogar 130% 164 165 // end of AbsBase.Pas 166 ///////////////////////////////////////////////////////////////////////////////// 167 ///////////////////////////////////////////////////////////////////////////////// 168 ///////////////////////////////////////////////////////////////////////////////// 169 170 171 172 ///////////////////////////////////////////////////////////////////////////////// 173 ///////////////////////////////////////////////////////////////////////////////// 174 ///////////////////////////////////////////////////////////////////////////////// 175 // DefBase.Pas 176 177 #define TextBoldBit 0x0001 /* Fett */ 178 #define TextRSlnBit 0x0002 /* Kursiv */ 179 #define TextUndlBit 0x0004 /* Unterstrichen */ 180 #define TextStrkBit 0x0008 /* Durchgesteichen */ 181 #define TextSupSBit 0x0010 /* Hocgestellt */ 182 #define TextSubSBit 0x0020 /* Tiefgestellt */ 183 #define TextKaptBit 0x0040 /* Kapitaelchen */ 184 #define TextLSlnBit 0x0080 /* Linkskursiv */ 185 #define TextDbUnBit 0x0100 /* Doppelt unterstrichen */ 186 #define TextDbStBit 0x0200 /* Doppelt durchgestrichen */ 187 #define TextSh2DBit 0x0400 /* 2D-Schatten 2.0 */ 188 #define TextSh3DBit 0x0800 /* 3D-Schatten 2.0 */ 189 #define TextSh4DBit 0x1000 /* 4D-Schatten 2.0 */ 190 #define TextShEbBit 0x2000 /* Embossed-Schatten 2.0 */ 191 #define FontAtrBits (TextBoldBit | TextRSlnBit) 192 193 #define THJustLeft 0x00 194 #define THJustCenter 0x01 195 #define THJustRight 0x02 196 #define THJustBlock 0x03 197 #define THJustDrvOut 0x04 /* Austreibend Formatiert */ 198 #define THJustLocked 0x05 /* A l s S p e r r s c h r i f t */ 199 #define TVJustTop 0x00 /* Future */ 200 #define TVJustCenter 0x10 /* Future */ 201 #define TVJustBottom 0x20 /* Future */ 202 #define TVJustBlock 0x30 /* Future */ 203 204 #define MaxCharSlant 4200 /* Maximal 42deg kursiv ! */ 205 206 // end of DefBase.Pas 207 ///////////////////////////////////////////////////////////////////////////////// 208 ///////////////////////////////////////////////////////////////////////////////// 209 ///////////////////////////////////////////////////////////////////////////////// 210 211 212 sal_Bool CheckTextOutl(ObjAreaType& F, ObjLineType& L); 213 214 sal_Bool CheckTextOutl(ObjAreaType& F, ObjLineType& L) 215 { 216 return (F.FIntens!=L.LIntens) || 217 ((F.FFarbe!=L.LFarbe) && (F.FIntens>0)) || 218 ((F.FBFarbe!=L.LBFarbe) && (F.FIntens<100)); 219 } 220 221 222 ///////////////////////////////////////////////////////////////////////////////// 223 ///////////////////////////////////////////////////////////////////////////////// 224 ///////////////////////////////////////////////////////////////////////////////// 225 // Misc.Pas 226 227 short hPoint2Sgf(short a) 228 { 229 long b; 230 b=long(a)*127*SgfDpmm/(144*5); 231 return short(b); 232 } 233 234 short Sgf2hPoint(short a) 235 { 236 long b; 237 b=long(a)*5*144/(127*SgfDpmm); 238 return short(b); 239 } 240 241 // End of Misc.Pas 242 ///////////////////////////////////////////////////////////////////////////////// 243 ///////////////////////////////////////////////////////////////////////////////// 244 ///////////////////////////////////////////////////////////////////////////////// 245 246 247 248 ///////////////////////////////////////////////////////////////////////////////// 249 ///////////////////////////////////////////////////////////////////////////////// 250 ///////////////////////////////////////////////////////////////////////////////// 251 // AbsRead.Pas 252 253 // ====================================================================== 254 // Function GetTopToBaseLine() Function GetBaseLineToBtm() 255 // 256 // Abstand von Zeilenoberkante bis BaseLine bzw. von BaseLine bis 257 // Unterkante berechnen. Alles in SGF-Units. 258 // ====================================================================== 259 260 sal_uInt16 GetTopToBaseLine(sal_uInt16 MaxGrad) 261 { 262 long ret; 263 ret=long(MaxGrad)*long(CharTopToBase) /long(100); 264 return sal_uInt16(ret); 265 } 266 267 // ====================================================================== 268 // Function GetTextChar() Function GetTextCharConv() 269 // 270 // Liest ein Zeichen aus dem Textbuffer, wertet dabei eventuell 271 // auftretende Escapesequenzen aus und setzt dementsprechend den 272 // Ein-/Ausgabeparameter AktAtr. Index wird entsprechend erhoeht. 273 // Der Parameter Rest muss immer die Anzahl der Zeichen beinhalten, 274 // den angeforderten Zeichen in der aktuellen Zeile noch folgen. 275 // Ansonsten funktioniert die Silbentrennung nicht richtig. Gibt man 276 // stattdessen die Konstante NoTrenn an, wird in keinem Fall 277 // getrennt, die Konstante DoTrenn bewirkt dagegen, dass ueberall dort 278 // getrennt wird, wo ein SoftTrenner vorkommt. 279 // 280 // SoftTrenner werden immer in ein Minuszeichen konvertiert. 281 // GetTextCharConv() konvertiert zusaetzlich HardSpace und AbsatzEnde 282 // in Spaces sowie HardTrenner in Minuszeichen. TextEnde wird immer 283 // als Char(0) geliefert. 284 // ====================================================================== 285 286 287 288 UCHAR ConvertTextChar(UCHAR c) 289 { 290 if (c<32) { 291 switch (c) { 292 case HardSpace : c=' '; break; 293 case AbsatzEnd : c=' '; break; 294 case SoftTrenn : c='-'; break; 295 case HardTrenn : c='-'; break; 296 case SoftTrennK : c='-'; break; 297 case SoftTrennAdd: c='-'; 298 } 299 } 300 return c; 301 } 302 303 304 305 sal_uInt16 GetSchnittBit(UCHAR c) 306 { 307 sal_uInt16 r=0; 308 switch (c) { 309 case EscBold : r=TextBoldBit; break; 310 case EscRSlnt: r=TextRSlnBit; break; 311 case EscUndln: r=TextUndlBit; break; 312 case EscStrik: r=TextStrkBit; break; 313 case EscDbUnd: r=TextDbUnBit; break; 314 case EscDbStk: r=TextDbStBit; break; 315 case EscSupSc: r=TextSupSBit; break; 316 case EscSubSc: r=TextSubSBit; break; 317 case EscKaptF: r=TextKaptBit; break; 318 case EscLSlnt: r=TextLSlnBit; break; 319 case Esc2DShd: r=TextSh2DBit; break; 320 case Esc3DShd: r=TextSh3DBit; break; 321 case Esc4DShd: r=TextSh4DBit; break; 322 case EscEbShd: r=TextShEbBit; 323 } 324 return r; 325 } 326 327 328 329 long ChgValue(long Def, long Min, long Max, UCHAR FlgVal, long NumVal) 330 { 331 long r=0; 332 333 if (FlgVal==EscDeflt) { 334 r=Def; // zurueck auf Default 335 } else { 336 if (NumVal!=EscNoVal) r=NumVal; // Hart setzen 337 } 338 339 if (Min!=0 || Max!=0) { 340 if (r>Max) r=Max; 341 if (r<Min) r=Min; 342 } 343 return r; 344 } 345 346 347 348 void ChgSchnittBit(sal_uInt16 Bit, sal_uInt16 Radio1, sal_uInt16 Radio2, sal_uInt16 Radio3, 349 UCHAR FlgVal, sal_uInt16 Schnitt0, sal_uInt16& Schnitt) 350 { 351 sal_uInt16 All,Rad; 352 353 Rad=Radio1 | Radio2 | Radio3; 354 All=Bit | Rad; 355 356 switch (FlgVal) { 357 case EscSet : Schnitt=(Schnitt & ~All) | Bit; break; 358 case EscReset: Schnitt=(Schnitt & ~All); break; 359 case EscDeflt: Schnitt=(Schnitt & ~All) | (Schnitt0 & All); break; 360 case EscToggl: Schnitt=(Schnitt & ~Rad) ^ Bit; 361 } 362 } 363 364 365 366 UCHAR GetNextChar(UCHAR* TBuf, sal_uInt16 Index) 367 { 368 sal_uInt16 Cnt; 369 while (TBuf[Index]==Escape) { 370 Index++; 371 Cnt=0; 372 while (TBuf[Index]!=Escape && Cnt<=MaxEscLen) { 373 Index++; Cnt++; } 374 Index++; 375 } 376 return TBuf[Index]; 377 } 378 379 380 381 UCHAR ProcessOne(UCHAR* TBuf, sal_uInt16& Index, 382 ObjTextType& Atr0, ObjTextType& AktAtr, 383 sal_Bool ScanEsc) 384 { 385 UCHAR c; 386 UCHAR Ident; 387 sal_Bool Ende; 388 sal_Bool q; 389 UCHAR FlgVal; 390 long NumVal; 391 long Sgn; 392 short i; 393 sal_Bool EoVal; 394 395 do { 396 c=TBuf[Index]; Index++; 397 Ende=(c!=Escape); 398 if (Ende==sal_False) { 399 c=TBuf[Index]; Index++; 400 Ident=c; // Identifer merken 401 FlgVal=EscNoFlg; 402 NumVal=EscNoVal; 403 c=TBuf[Index]; Index++; // Hier faengt der Wert an 404 if (c==EscSet || c==EscReset || c==EscDeflt || c==EscToggl) FlgVal=c; else { 405 if (c=='-') Sgn=-1; else Sgn=1; 406 if (c=='+' || c=='-') { c=TBuf[Index]; Index++; } 407 i=MaxEscValLen; 408 NumVal=0; 409 do { 410 NumVal=10*NumVal+c-'0'; 411 EoVal=(TBuf[Index]<'0' || TBuf[Index]>'9'); 412 if (EoVal==sal_False) { c=TBuf[Index]; Index++; } 413 i--; 414 } while (i>0 && EoVal==sal_False); 415 NumVal=Sgn*NumVal; 416 } 417 q=!CheckTextOutl(AktAtr.F,AktAtr.L); 418 419 switch (Ident) { 420 case EscFont : AktAtr.SetFont(sal_uLong (ChgValue(Atr0.GetFont(),0,0 ,FlgVal,NumVal)));break; 421 case EscGrad : AktAtr.Grad =sal_uInt16(ChgValue(Atr0.Grad, 2,2000 ,FlgVal,NumVal)); break; 422 case EscBreit: AktAtr.Breite =sal_uInt16(ChgValue(Atr0.Breite, 1,1000 ,FlgVal,NumVal)); break; 423 case EscKaptS: AktAtr.Kapit =(sal_uInt8)(ChgValue(Atr0.Kapit, 1,255 ,FlgVal,NumVal)); break; 424 case EscLFeed: AktAtr.LnFeed =sal_uInt16(ChgValue(Atr0.LnFeed, 1,65535 ,FlgVal,NumVal)); break; 425 case EscSlant: AktAtr.Slant =sal_uInt16(ChgValue(Atr0.Slant, 1,MaxCharSlant ,FlgVal,NumVal)); break; 426 case EscVPos : AktAtr.ChrVPos=char (ChgValue(Atr0.ChrVPos,-128,127 ,FlgVal,NumVal)); break; 427 case EscZAbst: AktAtr.ZAbst =(sal_uInt8)(ChgValue(Atr0.ZAbst, 1,255 ,FlgVal,NumVal)); break; 428 case EscHJust: AktAtr.Justify=(sal_uInt8)(ChgValue(Atr0.Justify & 0x0F,0,5 ,FlgVal,NumVal)); break; 429 case EscFarbe: { AktAtr.L.LFarbe =(sal_uInt8)(ChgValue(Atr0.L.LFarbe,0,7 ,FlgVal,NumVal)); if (q) AktAtr.F.FFarbe =AktAtr.L.LFarbe; } break; 430 case EscBFarb: { AktAtr.L.LBFarbe=(sal_uInt8)(ChgValue(Atr0.L.LBFarbe,0,255,FlgVal,NumVal)); if (q) AktAtr.F.FBFarbe=AktAtr.L.LBFarbe; } break; 431 case EscInts : { AktAtr.L.LIntens=(sal_uInt8)(ChgValue(Atr0.L.LIntens,0,100,FlgVal,NumVal)); if (q) AktAtr.F.FIntens=AktAtr.L.LIntens; } break; 432 433 case EscMustr: { AktAtr.F.FMuster=sal_uInt16(ChgValue(Atr0.F.FMuster,0,65535,FlgVal,NumVal)); } break; 434 case EscMFarb: { AktAtr.F.FFarbe =(sal_uInt8)(ChgValue(Atr0.F.FFarbe,0,7 ,FlgVal,NumVal)); } break; 435 case EscMBFrb: { AktAtr.F.FBFarbe=(sal_uInt8)(ChgValue(Atr0.F.FBFarbe,0,255,FlgVal,NumVal)); } break; 436 case EscMInts: { AktAtr.F.FIntens=(sal_uInt8)(ChgValue(Atr0.F.FIntens,0,100,FlgVal,NumVal)); } break; 437 438 case EscSMstr: { AktAtr.ShdF.FMuster=sal_uInt16(ChgValue(Atr0.ShdF.FMuster,0,65535,FlgVal,NumVal)); } break; 439 case EscSFarb: { AktAtr.ShdL.LFarbe =(sal_uInt8)(ChgValue(Atr0.ShdL.LFarbe,0,7 ,FlgVal,NumVal)); AktAtr.ShdF.FFarbe =AktAtr.ShdL.LFarbe; } break; 440 case EscSBFrb: { AktAtr.ShdL.LBFarbe=(sal_uInt8)(ChgValue(Atr0.ShdL.LBFarbe,0,255,FlgVal,NumVal)); AktAtr.ShdF.FBFarbe=AktAtr.ShdL.LBFarbe; } break; 441 case EscSInts: { AktAtr.ShdL.LIntens=(sal_uInt8)(ChgValue(Atr0.ShdL.LIntens,0,100,FlgVal,NumVal)); AktAtr.ShdF.FIntens=AktAtr.ShdL.LIntens; } break; 442 case EscSDist: { AktAtr.ShdVers.x=(short)ChgValue(Atr0.ShdVers.x,0,30000,FlgVal,NumVal); AktAtr.ShdVers.y=AktAtr.ShdVers.x; } break; 443 case EscSXDst: { AktAtr.ShdVers.x=(short)ChgValue(Atr0.ShdVers.x,0,30000,FlgVal,NumVal); } break; 444 case EscSYDst: { AktAtr.ShdVers.y=(short)ChgValue(Atr0.ShdVers.y,0,30000,FlgVal,NumVal); } break; 445 446 case EscBold : ChgSchnittBit(TextBoldBit,0,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 447 case EscRSlnt: ChgSchnittBit(TextRSlnBit,TextLSlnBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 448 case EscUndln: ChgSchnittBit(TextUndlBit,TextDbUnBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 449 case EscStrik: ChgSchnittBit(TextStrkBit,TextDbStBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 450 case EscDbUnd: ChgSchnittBit(TextDbUnBit,TextUndlBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 451 case EscDbStk: ChgSchnittBit(TextDbStBit,TextStrkBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 452 case EscSupSc: ChgSchnittBit(TextSupSBit,TextSubSBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 453 case EscSubSc: ChgSchnittBit(TextSubSBit,TextSupSBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 454 case EscKaptF: ChgSchnittBit(TextKaptBit,0,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 455 case EscLSlnt: ChgSchnittBit(TextLSlnBit,TextRSlnBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 456 case Esc2DShd: ChgSchnittBit(TextSh2DBit,TextSh3DBit,TextSh4DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 457 case Esc3DShd: ChgSchnittBit(TextSh3DBit,TextSh2DBit,TextSh4DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 458 case Esc4DShd: ChgSchnittBit(TextSh4DBit,TextSh2DBit,TextSh3DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 459 case EscEbShd: ChgSchnittBit(TextShEbBit,TextSh2DBit,TextSh3DBit,TextSh4DBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; 460 } //endcase 461 if (TBuf[Index]==Escape) Index++; // zweites Esc weglesen } 462 } // if Ende==sal_False 463 } while (Ende==sal_False && ScanEsc==sal_False); 464 if (Ende==sal_False) c=Escape; 465 return c; 466 } // end of ProcessOne 467 468 469 UCHAR GetTextChar(UCHAR* TBuf, sal_uInt16& Index, 470 ObjTextType& Atr0, ObjTextType& AktAtr, 471 sal_uInt16 Rest, sal_Bool ScanEsc) 472 { 473 UCHAR c,c0,nc; 474 475 c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); 476 if (ScanEsc==sal_False) { 477 if (c==SoftTrennAdd || c==SoftTrennK || c==SoftTrenn) { 478 nc=GetNextChar(TBuf,Index); 479 c0=c; 480 if (Rest==0 || Rest==DoTrenn || 481 nc==' ' || nc==AbsatzEnd || nc==TextEnd) c='-'; 482 else { 483 c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); // den Trenner ueberspringen 484 if (c0==SoftTrennAdd) { 485 if (c>=32) c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); // und hier noch 'nen Buchstaben ueberspringen 486 } 487 } 488 } 489 if ((Rest==1 || Rest==DoTrenn) && GetNextChar(TBuf,Index)==SoftTrennK) { 490 if (c=='c') c='k'; 491 else if (c=='C') c='K'; 492 } 493 } 494 return c; 495 } 496 497 // HardSpace und HardTrenn muessen explizit konvertiert werden ! } 498 // if AktAtr.Schnitt and TextKaptBit =TextKaptBit then c:=UpCase(c);(explizit) } 499 500 // Bei der Trennmethode SoftTrennAdd wird davon ausgegangen, dass der zu } 501 // trennende Konsonant bereits 3x mal im TextBuf vorhanden ist, z.b.: } 502 // "Schiff-fahrt". Wenn nicht getrennt, dann wird "-f" entfernt. } 503 504 505 506 UCHAR GetTextCharConv(UCHAR* TBuf, sal_uInt16& Index, 507 ObjTextType& Atr0, ObjTextType& AktAtr, 508 sal_uInt16 Rest, sal_Bool ScanEsc) 509 { 510 UCHAR c; 511 512 c=GetTextChar(TBuf,Index,Atr0,AktAtr,Rest,ScanEsc); 513 if (c<32) { 514 switch (c) { 515 case HardSpace : c=' '; break; 516 case AbsatzEnd : c=' '; break; 517 case HardTrenn : c='-'; 518 } 519 } 520 return c; 521 } 522 523 524 // ====================================================================== 525 // Function GetLineFeed() 526 // 527 // Benoetigter Zeilenabstand in SGF-Units. ChrVPos wird beruecksichtigt. 528 // ====================================================================== 529 sal_uInt16 GetLineFeed(UCHAR* TBuf, sal_uInt16 Index, ObjTextType Atr0, ObjTextType AktAtr, 530 sal_uInt16 nChar, sal_uInt16& LF, sal_uInt16& MaxGrad) 531 { 532 UCHAR c=0; 533 sal_Bool AbsEnd=sal_False; 534 sal_uLong LF100=0; 535 sal_uLong MaxLF100=0; 536 sal_Bool LFauto=0; 537 sal_Bool First=sal_True; 538 sal_uInt16 Grad; 539 sal_uInt16 i=0; 540 sal_uInt16 r=1; 541 542 MaxGrad=0; 543 while (!AbsEnd && nChar>0) { 544 nChar--; 545 c=GetTextChar(TBuf,Index,Atr0,AktAtr,nChar,sal_False); 546 i++; 547 AbsEnd=(c==TextEnd || c==AbsatzEnd); 548 if (First || (!AbsEnd && c!=' ' && c!=HardTrenn)) { 549 LFauto=(AktAtr.LnFeed & 0x8000)==0; 550 LF100=AktAtr.LnFeed & 0x7FFF; 551 if (LFauto) LF100=LF100*AktAtr.Grad; else LF100*=LF100; 552 if (AktAtr.ChrVPos>0) LF100-=AktAtr.ChrVPos*100; 553 if (LF100>MaxLF100) MaxLF100=LF100; 554 Grad=AktAtr.Grad; 555 if (AktAtr.ChrVPos>0) Grad=Grad-AktAtr.ChrVPos; 556 if (Grad>MaxGrad) MaxGrad=Grad; 557 First=sal_False; 558 } 559 if (!AbsEnd && c!=' ') r=i; 560 } 561 MaxGrad=hPoint2Sgf(MaxGrad); 562 if (MaxLF100<=4000) { // sonst Overflowgefahr 563 LF=sal_uInt16(hPoint2Sgf(short(MaxLF100)) /100); 564 } else { 565 LF=sal_uInt16(hPoint2Sgf(short(MaxLF100) /100)); 566 } 567 568 return r; 569 } 570 571 // End of AbsRead.Pas 572 ///////////////////////////////////////////////////////////////////////////////// 573 ///////////////////////////////////////////////////////////////////////////////// 574 ///////////////////////////////////////////////////////////////////////////////// 575 576 577 578 ///////////////////////////////////////////////////////////////////////////////// 579 ///////////////////////////////////////////////////////////////////////////////// 580 ///////////////////////////////////////////////////////////////////////////////// 581 // iFont.Pas 582 583 #define DefaultSlant 1500 /* Default: Italic ist 15deg */ 584 #define SuperSubFact 60 /* SuperScript/SubScript: 60% vom Schriftgrad */ 585 #define DefaultSpace 40 /* Default: Space ist 40% vom SchriftGrad */ 586 587 sal_uInt16 SetTextContext(OutputDevice& rOut, ObjTextType& Atr, sal_Bool Kapt, sal_uInt16 Dreh, 588 sal_uInt16 FitXMul, sal_uInt16 FitXDiv, sal_uInt16 FitYMul, sal_uInt16 FitYDiv) 589 { 590 SgfFontOne* pSgfFont; // Font aus dem IniFile 591 Font aFont; 592 Color aColor; 593 sal_uLong Grad; 594 sal_uLong Brei; 595 String FNam; 596 sal_uInt16 StdBrei=50; // Durchschnittliche Zeichenbreite in % von Schriftgrad 597 sal_Bool bFit=(FitXMul!=1 || FitXDiv!=1 || FitYMul!=1 || FitYDiv!=1); 598 599 pSgfFont = pSgfFonts->GetFontDesc(Atr.GetFont()); 600 601 if ( pSgfFont!=NULL ) 602 { 603 FNam =pSgfFont->SVFName; 604 StdBrei=pSgfFont->SVWidth; 605 if (pSgfFont->Fixd) aFont.SetPitch(PITCH_FIXED); else aFont.SetPitch(PITCH_VARIABLE); 606 aFont.SetFamily(pSgfFont->SVFamil); 607 aFont.SetCharSet(pSgfFont->SVChSet); 608 aFont.SetName(FNam); 609 } 610 else 611 { // Falls nich im Inifile, sind hier einige Fonts hart kodiert 612 aFont.SetPitch(PITCH_VARIABLE); 613 switch (Atr.GetFont()) { 614 case 92500: case 92501: case 92504: case 92505: 615 { 616 #if defined(WNT) || defined(PM2) 617 FNam=String::CreateFromAscii( "Times New Roman" ); // CG Times ist unter Windows und OS/2 Times New Roman 618 #else 619 FNam=String::CreateFromAscii( "Times" ); // ansonsten ist das einfach Times 620 #endif 621 StdBrei=40; 622 aFont.SetFamily(FAMILY_ROMAN); 623 } break; 624 case 94021: case 94022: case 94023: case 94024: { 625 #if defined(WNT) 626 FNam=String::CreateFromAscii( "Arial", 5 ); // Univers ist unter Windows Arial 627 #else 628 FNam=String::CreateFromAscii( "Helvetica" ); // und ansonsten Helvetica 629 #endif 630 aFont.SetFamily(FAMILY_SWISS); 631 StdBrei=47; 632 } break; 633 case 93950: case 93951: case 93952: case 93953: { 634 #if defined(WNT) 635 FNam=String::CreateFromAscii( "Courier New" ); // Der Vector-Courierfont unter Windows heisst Courier New 636 #else 637 FNam=String::CreateFromAscii( "Courier" ); // ansonsten ist und bleibt Courier immer Courier 638 #endif 639 aFont.SetFamily(FAMILY_ROMAN); 640 aFont.SetPitch(PITCH_FIXED); 641 } break; 642 default: FNam=String::CreateFromAscii( "Helvetica", 9 ); 643 } 644 aFont.SetName(FNam); 645 //aFont.SetCharSet(CHARSET_SYSTEM); 646 } 647 648 Grad=sal_uLong(Atr.Grad); 649 if ((Atr.Schnitt & TextKaptBit) !=0 && Kapt) Grad=Grad*sal_uLong(Atr.Kapit)/100; 650 if ((Atr.Schnitt & TextSupSBit) !=0 || (Atr.Schnitt & TextSubSBit) !=0) Grad=Grad*SuperSubFact/100; 651 Brei=Grad; 652 if (Atr.Breite!=100 || bFit) { 653 if (bFit) { 654 Grad=Grad*sal_uLong(FitYMul)/sal_uLong(FitYDiv); 655 Brei=Brei*sal_uLong(FitXMul)/sal_uLong(FitXDiv); 656 } 657 Brei=Brei*sal_uLong(Atr.Breite)/100; 658 Brei=Brei*sal_uLong(StdBrei)/100; 659 aFont.SetSize(Size(hPoint2Sgf(sal_uInt16(Brei)),hPoint2Sgf(sal_uInt16(Grad)))); 660 } else { 661 aFont.SetSize(Size(0,hPoint2Sgf(sal_uInt16(Grad)))); 662 } 663 664 aColor=Sgv2SvFarbe(Atr.L.LFarbe,Atr.L.LBFarbe,Atr.L.LIntens); aFont.SetColor(aColor); 665 aColor=Sgv2SvFarbe(Atr.F.FFarbe,Atr.F.FBFarbe,Atr.F.FIntens); aFont.SetFillColor(aColor); 666 aFont.SetTransparent(sal_True); 667 aFont.SetAlign(ALIGN_BASELINE); 668 669 Dreh/=10; Dreh=3600-Dreh; if (Dreh==3600) Dreh=0; 670 aFont.SetOrientation(Dreh); 671 672 if ((Atr.Schnitt & TextBoldBit) !=0) aFont.SetWeight(WEIGHT_BOLD); 673 if ((Atr.Schnitt & TextRSlnBit) !=0) aFont.SetItalic(ITALIC_NORMAL); 674 if ((Atr.Schnitt & TextUndlBit) !=0) aFont.SetUnderline(UNDERLINE_SINGLE); 675 if ((Atr.Schnitt & TextDbUnBit) !=0) aFont.SetUnderline(UNDERLINE_DOUBLE); 676 if ((Atr.Schnitt & TextStrkBit) !=0) aFont.SetStrikeout(STRIKEOUT_SINGLE); 677 if ((Atr.Schnitt & TextDbStBit) !=0) aFont.SetStrikeout(STRIKEOUT_DOUBLE); 678 if ((Atr.Schnitt & TextSh2DBit) !=0) aFont.SetShadow(sal_True); 679 if ((Atr.Schnitt & TextSh3DBit) !=0) aFont.SetShadow(sal_True); 680 if ((Atr.Schnitt & TextSh4DBit) !=0) aFont.SetShadow(sal_True); 681 if ((Atr.Schnitt & TextShEbBit) !=0) aFont.SetShadow(sal_True); 682 if (CheckTextOutl(Atr.F,Atr.L)) aFont.SetOutline(sal_True); 683 684 if (aFont!=rOut.GetFont()) rOut.SetFont(aFont); 685 686 return 0; 687 } 688 689 // iFont.Pas 690 ///////////////////////////////////////////////////////////////////////////////// 691 ///////////////////////////////////////////////////////////////////////////////// 692 ///////////////////////////////////////////////////////////////////////////////// 693 694 695 ///////////////////////////////////////////////////////////////////////////////// 696 ///////////////////////////////////////////////////////////////////////////////// 697 ///////////////////////////////////////////////////////////////////////////////// 698 // Absatz.Pas 699 700 struct ProcChrSta { 701 sal_uInt16 Index; 702 sal_uInt16 ChrXP; 703 UCHAR OutCh; 704 sal_Bool Kapt; 705 ObjTextType Attrib; 706 }; 707 708 void InitProcessCharState(ProcChrSta& State, ObjTextType& AktAtr, sal_uInt16 IndexA) 709 { 710 State.Attrib=AktAtr; 711 State.OutCh=0; 712 State.Index=IndexA; 713 State.ChrXP=0; 714 State.Kapt=sal_False; 715 } 716 717 sal_Bool UpcasePossible(UCHAR c) 718 { 719 if ((c>='a' && c<='z') || c == 0xe4 || c == 0xf6 || c == 0xfc ) return sal_True; 720 else return sal_False; 721 } 722 723 UCHAR Upcase(UCHAR c) 724 { 725 if ((c>=(UCHAR)'a' && c<=(UCHAR)'z')) c=(c-(UCHAR)'a')+(UCHAR)'A'; 726 else if ( c == 0xe4 ) c = 0xc4; 727 else if ( c == 0xf6 ) c = 0xd6; 728 else if ( c == 0xfc ) c = 0xdc; 729 return c; 730 } 731 732 sal_uInt16 GetCharWidth(OutputDevice& rOut, UCHAR c) 733 { 734 UCHAR c1; 735 sal_uInt16 ChrWidth; 736 737 c1 = ByteString::Convert((char)c,RTL_TEXTENCODING_IBM_437, gsl_getSystemTextEncoding() ); 738 if (c==' ') 739 { 740 ChrWidth=(sal_uInt16)rOut.GetTextWidth( String('A') ); 741 if (rOut.GetFont().GetPitch()!=PITCH_FIXED) { 742 ChrWidth=MulDiv(ChrWidth,DefaultSpace,100); 743 } 744 } else { 745 // with MaxChar == 255 c cannot be greater than MaxChar 746 // assert if MaxChar is ever changed 747 OSL_ENSURE( MaxChar == 255, "MaxChar not 255" ); 748 if (c>=MinChar /*&& c<=MaxChar*/) 749 { 750 ChrWidth=(sal_uInt16)rOut.GetTextWidth(String((char)c1)); 751 } 752 else 753 { 754 ChrWidth=(sal_uInt16)rOut.GetTextWidth(String('A')); 755 } 756 } 757 return ChrWidth; 758 } 759 760 UCHAR ProcessChar(OutputDevice& rOut, UCHAR* TBuf, ProcChrSta& R, ObjTextType& Atr0, 761 sal_uInt16& nChars, sal_uInt16 Rest, 762 short* Line, UCHAR* cLine) 763 { 764 sal_uInt16 KernDist=0; // Wert fuer Kerning 765 sal_uInt16 ChrWidth; 766 UCHAR c; 767 UCHAR c1; 768 sal_Bool AbsEnd; 769 770 c=GetTextChar(TBuf,R.Index,Atr0,R.Attrib,Rest,sal_False); // versucht evtl. zu trennen, wenn Rest entsprechenden Wert besitzt 771 772 AbsEnd=(c==AbsatzEnd || c==TextEnd); 773 if (AbsEnd==sal_False) { 774 R.OutCh=ConvertTextChar(c); // von HardTrenn nach '-', ... 775 R.Kapt=(R.Attrib.Schnitt & TextKaptBit) !=0 && UpcasePossible(R.OutCh); 776 if (R.Kapt) R.OutCh=Upcase(R.OutCh); 777 SetTextContext(rOut,R.Attrib,R.Kapt,0,1,1,1,1); 778 779 if (R.Kapt) c1=Upcase(c); else c1=c; 780 ChrWidth=GetCharWidth(rOut,c1); 781 782 if (R.Attrib.ZAbst!=100) { // Spezial-Zeichenabstand ? 783 sal_uLong Temp; 784 Temp=sal_uLong(ChrWidth)*sal_uLong(R.Attrib.ZAbst)/100; 785 ChrWidth=sal_uInt16(Temp); 786 } 787 nChars++; 788 if (R.ChrXP>32000) R.ChrXP=32000; 789 Line[nChars]=R.ChrXP-KernDist; 790 cLine[nChars]=c; 791 R.ChrXP+=ChrWidth-KernDist; // Position fuer den naechsten Character 792 } 793 return c; 794 } 795 796 void FormatLine(UCHAR* TBuf, sal_uInt16& Index, ObjTextType& Atr0, ObjTextType& AktAtr, 797 sal_uInt16 UmbWdt, sal_uInt16 AdjWdt, 798 short* Line, sal_uInt16& nChars, 799 double, double, 800 UCHAR* cLine, sal_Bool TextFit) 801 { 802 VirtualDevice vOut; 803 UCHAR c,c0; 804 UCHAR ct; 805 sal_Bool First; // erster Char ? 806 sal_uInt8 Just = 0; // Absatzformatierung 807 sal_Bool Border; // Rand der Box erreicht ? 808 sal_Bool Border0; 809 sal_Bool AbsEnd; // Ende des Absatzes erreicht ? 810 ProcChrSta* R=new ProcChrSta; 811 ProcChrSta* R0=new ProcChrSta; 812 ProcChrSta* WErec=new ProcChrSta; 813 sal_uInt16 WEnChar; 814 ProcChrSta* WErec0=new ProcChrSta; 815 sal_uInt16 WEnChar0; 816 ProcChrSta* TRrec=new ProcChrSta; 817 sal_uInt16 TRnChar; 818 819 sal_uInt16 WordEndCnt; // Justieren und Trennen 820 sal_Bool WordEnd; 821 sal_Bool Trenn; 822 823 short BoxRest; // zum Quetschen und formatieren 824 sal_uInt16 i,j,k,h; 825 sal_uInt16 re,li; 826 827 vOut.SetMapMode(MapMode(MAP_10TH_MM,Point(),Fraction(1,4),Fraction(1,4))); 828 829 nChars=0; 830 SetTextContext(vOut,AktAtr,sal_False,0,1,1,1,1); 831 InitProcessCharState(*R,AktAtr,Index); 832 (*R0)=(*R); (*WErec)=(*R); WEnChar=0; c0=0; Border0=sal_False; 833 Border=sal_False; First=sal_True; 834 WordEndCnt=0; 835 836 do { // mal schauen, wieviele Worte so in die Zeile passen 837 if (Border) c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,DoTrenn,Line,cLine); 838 else c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,NoTrenn,Line,cLine); 839 AbsEnd=(c==AbsatzEnd || c==TextEnd); 840 //if not AbsEnd then 841 { 842 if (First) { 843 Just=R->Attrib.Justify & 0x0F; // Absatzformat steht wenn, dann am Anfang 844 } 845 Border=R->ChrXP>UmbWdt; 846 WordEnd=(AbsEnd || (c==' ')) && (c0!=' ') && (c0!=0); 847 Trenn=c=='-'; 848 if (WordEnd && !Border0) { 849 WordEndCnt++; 850 (*WErec)=(*R0); 851 WEnChar=nChars-1; 852 } 853 if (Trenn && !Border) { 854 WordEndCnt++; 855 (*WErec)=(*R); 856 WEnChar=nChars; 857 } 858 } 859 (*R0)=(*R); c0=c; 860 Border0=Border; 861 First=sal_False; 862 AbsEnd=AbsEnd || (nChars>=MaxLineChars); 863 } while (!(AbsEnd || (Border && ((WordEndCnt>0) || WordEnd || Trenn)))); 864 865 if (Border) { // Trennen und Quetschen 866 (*WErec0)=(*WErec); WEnChar0=WEnChar; 867 AbsEnd=sal_False; c0=0; 868 (*R)=(*WErec); nChars=WEnChar; 869 (*TRrec)=(*R); TRnChar=nChars; 870 Border0=sal_False; Border=sal_False; 871 do { // erst mal gucken wieviele Silben noch reinpassen 872 ct=ProcessChar(vOut,TBuf,*TRrec,Atr0,TRnChar,DoTrenn,Line,cLine); 873 c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,NoTrenn,Line,cLine); 874 AbsEnd=(ct==AbsatzEnd) || (ct==TextEnd) || (nChars>=MaxLineChars); 875 876 Border=TRrec->ChrXP>UmbWdt; 877 WordEnd=AbsEnd || ((AbsEnd || (c==' ')) && (c0!=' ') && (c0!=0)); 878 Trenn=ct=='-'; 879 if (WordEnd && (!Border0 || (WordEndCnt==0))) { 880 WordEndCnt++; 881 (*WErec)=(*R0); 882 if (AbsEnd) WEnChar=nChars; else WEnChar=nChars-1; 883 (*TRrec)=(*R); TRnChar=nChars; // zum weitersuchen 884 } 885 if (Trenn && (!Border || (WordEndCnt==0))) { 886 WordEndCnt++; // merken, dass man hier trennen kann 887 (*WErec)=(*TRrec); 888 WEnChar=TRnChar; 889 (*TRrec)=(*R); TRnChar=nChars; // zum weitersuchen 890 } 891 (*R0)=(*R); c0=c; 892 Border0=Border; 893 Border=R->ChrXP>UmbWdt; 894 } while (!(AbsEnd || (Border && ((WordEndCnt>0) || WordEnd || Trenn)))); 895 896 while (WErec0->Index<WErec->Index) { // damit Line[] auch garantiert stimmt } 897 c=ProcessChar(vOut,TBuf,*WErec0,Atr0,WEnChar0,WEnChar-WEnChar0-1,Line,cLine); 898 } 899 900 (*R)=(*WErec); nChars=WEnChar; 901 902 if (UmbWdt>=R->ChrXP) { 903 BoxRest=UmbWdt-R->ChrXP; 904 } else { // Zusammenquetschen 905 BoxRest=R->ChrXP-UmbWdt; // um soviel muss gequetscht werden 906 for (i=2;i<=nChars;i++) { // 1. CharPosition bleibt ! 907 Line[i]-=(i-1)*(BoxRest) /(nChars-1); 908 } 909 R->ChrXP=UmbWdt; 910 Line[nChars+1]=UmbWdt; 911 } 912 } 913 914 if (!AbsEnd) { 915 do { // Leerzeichen weglesen 916 (*WErec)=(*R); 917 c=GetTextChar(TBuf,R->Index,Atr0,R->Attrib,NoTrenn,sal_False); 918 nChars++; 919 Line[nChars]=R->ChrXP; 920 cLine[nChars]=c; 921 } while (c==' '); 922 if (c!=' ' && c!=AbsatzEnd && c!=TextEnd) { 923 nChars--; 924 (*R)=(*WErec); 925 } 926 } 927 928 if (AbsEnd && nChars<MaxLineChars) { // Ausrichten, statt Blocksatz aber linksbuendig 929 if (Just==3) Just=0; 930 nChars++; Line[nChars]=R->ChrXP; // Damit AbsatzEnde auch weggelesen wird 931 Line[nChars+1]=R->ChrXP; // denn die Breite von CR oder #0 ist nun mal sehr klein 932 if (TBuf[R->Index-1]!=AbsatzEnd && TBuf[R->Index-1]!=TextEnd) { 933 c=GetTextChar(TBuf,R->Index,Atr0,R->Attrib,NoTrenn,sal_False); // Kleine Korrektur. Notig, wenn nur 1 Wort in 934 } 935 } 936 937 BoxRest=AdjWdt-R->ChrXP; 938 if (TextFit) Just=THJustLeft; 939 940 switch (Just) { 941 case THJustLeft: break; // Links 942 case THJustCenter: { 943 BoxRest=BoxRest /2; // Mitte 944 for (i=1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; 945 } break; 946 case THJustRight: { // Rechts 947 for (i=1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; 948 } break; 949 case THJustDrvOut: 950 case THJustBlock: { // Block und Austreibend 951 re=nChars; 952 if (Just==THJustDrvOut) re--; 953 while (re>=1 && (cLine[re]==' ' || cLine[re]==TextEnd || cLine[re]==AbsatzEnd)) re--; 954 li=1; 955 while (li<=re && (cLine[li]==' ' || cLine[li]==TextEnd || cLine[li]==AbsatzEnd)) li++; 956 if (Just==THJustDrvOut) BoxRest=AdjWdt-Line[re+1]; 957 958 j=0; // Anzahl der Spaces ermitteln 959 for (i=li;i<=re;i++) { 960 if (cLine[i]==' ') { 961 j++; 962 } 963 } 964 965 if (j==0) { // nur 1 Wort ? -> Strecken ! 966 for (i=li+1;i<=re;i++) { // von links nach rechts 967 Line[i]=Line[i]+MulDiv(i-li,BoxRest,re-li+1-1); 968 } 969 } else { 970 k=0; h=0; 971 for (i=li;i<=re;i++) { // j Spaces aufbohren ! 972 if (cLine[i]==' ') { // Space gefunden ! 973 k++; 974 h=MulDiv(k,BoxRest,j); 975 } 976 Line[i]=Line[i]+h; 977 } 978 } 979 for (i=re+1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; // und den Rest anpassen 980 Line[nChars+1]=AdjWdt; 981 } break; 982 case THJustLocked: { //Gesperrt 983 re=nChars-1; 984 while (re>=1 && (cLine[re]==' ' || cLine[re]==TextEnd || cLine[re]==AbsatzEnd)) re--; 985 li=1; 986 while (li<=re && (cLine[li]==' ' || cLine[li]==TextEnd || cLine[li]==AbsatzEnd)) li++; 987 BoxRest=AdjWdt-Line[re+1]; 988 for (i=li+1;i<=re;i++) { // Strecken von links nach rechts 989 Line[i]=Line[i]+MulDiv(i-li,BoxRest,re-li+1-1); 990 } 991 for (i=re+1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; // und den Rest anpassen 992 Line[nChars+1]=AdjWdt; 993 } break; 994 } 995 Index=R->Index; 996 AktAtr=R->Attrib; 997 delete R; 998 delete R0; 999 delete WErec; 1000 delete WErec0; 1001 delete TRrec; 1002 } 1003 1004 1005 1006 // End of Absatz.Pas 1007 ///////////////////////////////////////////////////////////////////////////////// 1008 ///////////////////////////////////////////////////////////////////////////////// 1009 ///////////////////////////////////////////////////////////////////////////////// 1010 1011 1012 ///////////////////////////////////////////////////////////////////////////////// 1013 ///////////////////////////////////////////////////////////////////////////////// 1014 ///////////////////////////////////////////////////////////////////////////////// 1015 // DrawText.Pas 1016 1017 void DrawChar(OutputDevice& rOut, UCHAR c, ObjTextType T, PointType Pos, sal_uInt16 DrehWink, 1018 sal_uInt16 FitXMul, sal_uInt16 FitXDiv, sal_uInt16 FitYMul, sal_uInt16 FitYDiv) 1019 { 1020 SetTextContext(rOut,T,UpcasePossible(c),DrehWink,FitXMul,FitXDiv,FitYMul,FitYDiv); 1021 if ((T.Schnitt & TextKaptBit)!=0 && UpcasePossible(c)) c=Upcase(c); 1022 String s( (char)c, RTL_TEXTENCODING_IBM_437 ); 1023 rOut.DrawText( Point( Pos.x, Pos.y ), s ); 1024 } 1025 1026 /************************************************************************* 1027 |* 1028 |* TextType::Draw() 1029 |* 1030 |* Beschreibung 1031 |* Ersterstellung JOE 09.08.93 1032 |* Letzte Aenderung JOE 09.08.93 1033 |* 1034 *************************************************************************/ 1035 void TextType::Draw(OutputDevice& rOut) 1036 { 1037 if ((Flags & TextOutlBit)!=0) return; // Sourcetext fuer Outliner !! 1038 1039 ObjTextType T1,T2; 1040 sal_uInt16 Index1; 1041 sal_uInt16 Index2; 1042 UCHAR c = TextEnd; 1043 sal_uInt16 l; // Anzahl der Zeichen in der Zeile 1044 sal_uInt16 i; 1045 short yPos0; 1046 short xPos; 1047 short yPos; 1048 sal_uInt16 LF; 1049 sal_uInt16 MaxGrad; 1050 short xSize; 1051 short xSAdj; 1052 short ySize; 1053 double sn,cs; 1054 sal_uInt16 TopToBase; 1055 sal_Bool Ende = 0; 1056 sal_uInt16 lc; 1057 sal_Bool LineFit; // FitSize.x=0? oder Flags -> jede Zeile stretchen 1058 sal_Bool TextFit; 1059 short* xLine; 1060 UCHAR* cLine; // Buffer fuer FormatLine 1061 sal_uInt16 FitXMul; 1062 sal_uInt16 FitXDiv; 1063 sal_uInt16 FitYMul; 1064 sal_uInt16 FitYDiv; 1065 sal_Bool Fehler; 1066 UCHAR* Buf=Buffer; // Zeiger auf die Buchstaben 1067 1068 pSgfFonts->ReadList(); 1069 xLine=new short[ChrXPosArrSize]; 1070 cLine=new UCHAR[CharLineSize]; 1071 1072 TextFit=(Flags & TextFitBits)!=0; 1073 LineFit=sal_False; 1074 LineFit=((Flags & TextFitZBit)!=0); 1075 if (TextFit && FitSize.x==0) LineFit=sal_True; 1076 1077 if (DrehWink==0) { 1078 sn=0.0; 1079 cs=1.0; 1080 } else { 1081 sn=sin(double(DrehWink)*3.14159265359/18000); 1082 cs=cos(double(DrehWink)*3.14159265359/18000); 1083 } 1084 1085 T1=T; Index1=0; yPos=0; xPos=0; 1086 if (TextFit) { 1087 ySize=Pos2.y-Pos1.y; 1088 xSize=32000 /2; // Umbruch 1089 xSAdj=Pos2.x-Pos1.x; // zum Ausrichten bei Zentriert/Blocksatz 1090 //if (xSize<=0) { xSize=32000 /2; LineFit=sal_True; } 1091 FitXMul=sal::static_int_cast< sal_uInt16 >(abs(Pos2.x-Pos1.x)); FitXDiv=FitSize.x; if (FitXDiv==0) FitXDiv=1; 1092 FitYMul=sal::static_int_cast< sal_uInt16 >(abs(Pos2.y-Pos1.y)); FitYDiv=FitSize.y; if (FitYDiv==0) FitYDiv=1; 1093 } else { 1094 xSize=Pos2.x-Pos1.x; 1095 xSAdj=xSize; 1096 ySize=Pos2.y-Pos1.y; 1097 FitXMul=1; FitXDiv=1; 1098 FitYMul=1; FitYDiv=1; 1099 } 1100 if (xSize<0) xSize=0; 1101 if (xSAdj<0) xSAdj=0; 1102 1103 do { 1104 T2=T1; Index2=Index1; 1105 FormatLine(Buf,Index2,T,T2,xSize,xSAdj,xLine,l,sn,cs,cLine,LineFit); 1106 Fehler=(Index2==Index1); 1107 if (!Fehler) { 1108 lc=GetLineFeed(Buf,Index1,T,T1,l,LF,MaxGrad); 1109 if (TextFit) { 1110 if (LineFit) FitXDiv=xLine[lc+1]; 1111 if (FitXDiv>0) { 1112 long Temp; 1113 for (i=1;i<=l+1;i++) { 1114 Temp=long(xLine[i])*long(FitXMul) /long(FitXDiv); 1115 xLine[i]=short(Temp); 1116 } 1117 LF=MulDiv(LF,FitYMul,FitYDiv); 1118 MaxGrad=MulDiv(MaxGrad,FitYMul,FitYDiv); 1119 } else { 1120 FitXDiv=1; // 0 gibts nicht 1121 } 1122 } 1123 yPos0=yPos; 1124 TopToBase=GetTopToBaseLine(MaxGrad); 1125 yPos=yPos+TopToBase; 1126 Ende=(yPos0+short(MulDiv(MaxGrad,CharTopToBtm,100))>ySize) && !TextFit; 1127 if (!Ende) { 1128 T2=T1; Index2=Index1; 1129 i=1; 1130 while (i<=l) { 1131 c=GetTextCharConv(Buf,Index2,T,T2,l-i,sal_False); 1132 long xp1,yp1; // wegen Overflowgefahr 1133 PointType Pos; 1134 xp1=long(Pos1.x)+xPos+long(xLine[i]); 1135 yp1=long(Pos1.y)+yPos; 1136 if (xp1>32000) xp1=32000; if (xp1<-12000) xp1=-12000; 1137 if (yp1>32000) yp1=32000; if (yp1<-12000) yp1=-12000; 1138 Pos.x=short(xp1); 1139 Pos.y=short(yp1); 1140 1141 if (DrehWink!=0) RotatePoint(Pos,Pos1.x,Pos1.y,sn,cs); 1142 DrawChar(rOut,c,T2,Pos,DrehWink,FitXMul,FitXDiv,FitYMul,FitYDiv); 1143 i++; 1144 } // while i<=l 1145 yPos=yPos0+LF; 1146 T1=T2; Index1=Index2; // Fuer die naechste Zeile 1147 } // if ObjMin.y+yPos<=Obj_Max.y 1148 } // if !Fehler 1149 } while (c!=TextEnd && !Ende && !Fehler); 1150 delete[] cLine; 1151 delete[] xLine; 1152 } 1153 1154 // End of DrawText.Pas 1155 ///////////////////////////////////////////////////////////////////////////////// 1156 ///////////////////////////////////////////////////////////////////////////////// 1157 ///////////////////////////////////////////////////////////////////////////////// 1158 1159 // nicht mehr benoetigt, da der Pointer nun extra gefuehrt wird 1160 // (DEC Alpha hat naemlich 64Bit-Pointer!) 1161 //UCHAR* TextType::GetBufPtr() 1162 //{ 1163 // sal_uLong Temp; 1164 // Temp=sal_uLong(BufLo)+0x00010000*sal_uLong(BufHi); 1165 // return (UCHAR*)Temp; 1166 //} 1167 // 1168 //void TextType::SetBufPtr(UCHAR* Ptr) 1169 //{ 1170 // sal_uLong Temp=(sal_uLong)Ptr; 1171 // BufLo=sal_uInt16(Temp & 0x0000FFFF); 1172 // BufHi=sal_uInt16((Temp & 0xFFFF0000)>>16); 1173 //} 1174 1175 sal_uInt32 ObjTextType::GetFont() 1176 { 1177 return sal_uLong(FontLo)+0x00010000*sal_uLong(FontHi); 1178 } 1179 1180 void ObjTextType::SetFont(sal_uInt32 FontID) 1181 { 1182 FontLo=sal_uInt16(FontID & 0x0000FFFF); 1183 FontHi=sal_uInt16((FontID & 0xFFFF0000)>>16); 1184 } 1185 1186 1187 ///////////////////////////////////////////////////////////////////////////////// 1188 // SGF.Ini lesen //////////////////////////////////////////////////////////////// 1189 ///////////////////////////////////////////////////////////////////////////////// 1190 SgfFontOne::SgfFontOne() 1191 { 1192 Next=NULL; 1193 IFID=0; 1194 Bold=sal_False; 1195 Ital=sal_False; 1196 Sans=sal_False; 1197 Serf=sal_False; 1198 Fixd=sal_False; 1199 SVFamil=FAMILY_DONTKNOW; 1200 SVChSet=RTL_TEXTENCODING_DONTKNOW; 1201 SVWidth=40; 1202 } 1203 1204 void SgfFontOne::ReadOne( ByteString& ID, ByteString& Dsc ) 1205 { 1206 sal_uInt16 i,j,n; 1207 ByteString s; 1208 1209 if ( Dsc.Len() < 4 || ( Dsc.GetChar( 0 ) != '(' ) ) 1210 return; 1211 i=1; // Erster Buchstabe des IF-Fontnamen. Davor ist eine '(' 1212 while ( i < Dsc.Len() && ( Dsc.GetChar( i ) !=')' ) ) 1213 i++; 1214 Dsc.Erase(0,i+1); // IF-Fontname loeschen inkl. () 1215 1216 if ( Dsc.Len() < 2 || ( Dsc.GetChar( Dsc.Len() - 1 ) !=')' ) ) 1217 return; 1218 i=Dsc.Len()-2; // hier ist die ')' des SV-Fontnames 1219 j=0; 1220 while ( i > 0 && ( Dsc.GetChar( i ) != '(' ) ) 1221 { 1222 i--; 1223 j++; 1224 } 1225 SVFName=String(Dsc,i+1,j); // SV-Fontname rausholen 1226 Dsc.Erase(i,j); 1227 1228 IFID = (sal_uInt32)ID.ToInt32(); 1229 n=Dsc.GetTokenCount(' '); 1230 for (i=0;i<n;i++) 1231 { 1232 s = Dsc.GetToken( i,' ' ); 1233 if ( s.Len() ) 1234 { 1235 s.ToUpperAscii(); 1236 if ( s.CompareTo( "BOLD", 4 ) == COMPARE_EQUAL ) Bold=sal_True; 1237 else if ( s.CompareTo( "ITAL", 4 ) == COMPARE_EQUAL ) Ital=sal_True; 1238 else if ( s.CompareTo( "SERF", 4 ) == COMPARE_EQUAL ) Serf=sal_True; 1239 else if ( s.CompareTo( "SANS", 4 ) == COMPARE_EQUAL ) Sans=sal_True; 1240 else if ( s.CompareTo( "FIXD", 4 ) == COMPARE_EQUAL ) Fixd=sal_True; 1241 else if ( s.CompareTo( "ROMAN", 5 ) == COMPARE_EQUAL ) SVFamil=FAMILY_ROMAN; 1242 else if ( s.CompareTo( "SWISS", 5 ) == COMPARE_EQUAL ) SVFamil=FAMILY_SWISS; 1243 else if ( s.CompareTo( "MODERN", 6 ) == COMPARE_EQUAL ) SVFamil=FAMILY_MODERN; 1244 else if ( s.CompareTo( "SCRIPT", 6 ) == COMPARE_EQUAL ) SVFamil=FAMILY_SCRIPT; 1245 else if ( s.CompareTo( "DECORA", 6 ) == COMPARE_EQUAL ) SVFamil=FAMILY_DECORATIVE; 1246 else if ( s.CompareTo( "ANSI", 4 ) == COMPARE_EQUAL ) SVChSet=RTL_TEXTENCODING_MS_1252; 1247 else if ( s.CompareTo( "IBMPC", 5 ) == COMPARE_EQUAL ) SVChSet=RTL_TEXTENCODING_IBM_850; 1248 else if ( s.CompareTo( "MAC", 3 ) == COMPARE_EQUAL ) SVChSet=RTL_TEXTENCODING_APPLE_ROMAN; 1249 else if ( s.CompareTo( "SYMBOL", 6 ) == COMPARE_EQUAL ) SVChSet=RTL_TEXTENCODING_SYMBOL; 1250 else if ( s.CompareTo( "SYSTEM", 6 ) == COMPARE_EQUAL ) SVChSet = gsl_getSystemTextEncoding(); 1251 else if ( s.IsNumericAscii() ) SVWidth=sal::static_int_cast< sal_uInt16 >(s.ToInt32()); 1252 } 1253 } 1254 } 1255 1256 ///////////////////////////////////////////////////////////////////////////////// 1257 1258 SgfFontLst::SgfFontLst() 1259 { 1260 pList=NULL; 1261 Last=NULL; 1262 LastID=0; 1263 LastLn=NULL; 1264 Tried=sal_False; 1265 } 1266 1267 SgfFontLst::~SgfFontLst() 1268 { 1269 RausList(); 1270 } 1271 1272 void SgfFontLst::RausList() 1273 { 1274 SgfFontOne* P; 1275 SgfFontOne* P1; 1276 P=pList; 1277 while (P!=NULL) { 1278 P1=P->Next; 1279 delete P; 1280 P=P1; 1281 } 1282 pList=NULL; 1283 Last=NULL; 1284 Tried=sal_False; 1285 LastID=0; 1286 LastLn=NULL; 1287 } 1288 1289 void SgfFontLst::AssignFN(const String& rFName) 1290 { FNam=rFName; } 1291 1292 void SgfFontLst::ReadList() 1293 { 1294 if (!Tried) { 1295 Tried=sal_True; 1296 LastID=0; 1297 LastLn=NULL; 1298 SgfFontOne* P,P1; 1299 Config aCfg(FNam); 1300 aCfg.SetGroup("SGV Fonts fuer StarView"); 1301 sal_uInt16 Anz=aCfg.GetKeyCount(); 1302 sal_uInt16 i; 1303 ByteString FID,Dsc; 1304 1305 for (i=0;i<Anz;i++) 1306 { 1307 FID = aCfg.GetKeyName( i ); 1308 FID = FID.EraseAllChars(); // Leerzeichen weg 1309 Dsc = aCfg.ReadKey( i ); 1310 if ( FID.IsNumericAscii() ) 1311 { 1312 P=new SgfFontOne; // neuer Eintrag 1313 if (Last!=NULL) Last->Next=P; else pList=P; Last=P; // einklinken 1314 P->ReadOne(FID,Dsc); // und Zeile interpretieren 1315 } 1316 } 1317 } 1318 } 1319 1320 SgfFontOne* SgfFontLst::GetFontDesc(sal_uInt32 ID) 1321 { 1322 if (ID!=LastID) { 1323 SgfFontOne* P; 1324 P=pList; 1325 while (P!=NULL && P->IFID!=ID) P=P->Next; 1326 LastID=ID; 1327 LastLn=P; 1328 } 1329 return LastLn; 1330 } 1331