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