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
CheckTextOutl(ObjAreaType & F,ObjLineType & L)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
hPoint2Sgf(short a)227 short hPoint2Sgf(short a)
228 {
229 long b;
230 b=long(a)*127*SgfDpmm/(144*5);
231 return short(b);
232 }
233
Sgf2hPoint(short a)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
GetTopToBaseLine(sal_uInt16 MaxGrad)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
ConvertTextChar(UCHAR c)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
GetSchnittBit(UCHAR c)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
ChgValue(long Def,long Min,long Max,UCHAR FlgVal,long NumVal)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
ChgSchnittBit(sal_uInt16 Bit,sal_uInt16 Radio1,sal_uInt16 Radio2,sal_uInt16 Radio3,UCHAR FlgVal,sal_uInt16 Schnitt0,sal_uInt16 & Schnitt)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
GetNextChar(UCHAR * TBuf,sal_uInt16 Index)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
ProcessOne(UCHAR * TBuf,sal_uInt16 & Index,ObjTextType & Atr0,ObjTextType & AktAtr,sal_Bool ScanEsc)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
GetTextChar(UCHAR * TBuf,sal_uInt16 & Index,ObjTextType & Atr0,ObjTextType & AktAtr,sal_uInt16 Rest,sal_Bool ScanEsc)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
GetTextCharConv(UCHAR * TBuf,sal_uInt16 & Index,ObjTextType & Atr0,ObjTextType & AktAtr,sal_uInt16 Rest,sal_Bool ScanEsc)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 // ======================================================================
GetLineFeed(UCHAR * TBuf,sal_uInt16 Index,ObjTextType Atr0,ObjTextType AktAtr,sal_uInt16 nChar,sal_uInt16 & LF,sal_uInt16 & MaxGrad)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
SetTextContext(OutputDevice & rOut,ObjTextType & Atr,sal_Bool Kapt,sal_uInt16 Dreh,sal_uInt16 FitXMul,sal_uInt16 FitXDiv,sal_uInt16 FitYMul,sal_uInt16 FitYDiv)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(OS2)
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
InitProcessCharState(ProcChrSta & State,ObjTextType & AktAtr,sal_uInt16 IndexA)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
UpcasePossible(UCHAR c)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
Upcase(UCHAR c)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
GetCharWidth(OutputDevice & rOut,UCHAR c)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
ProcessChar(OutputDevice & rOut,UCHAR * TBuf,ProcChrSta & R,ObjTextType & Atr0,sal_uInt16 & nChars,sal_uInt16 Rest,short * Line,UCHAR * cLine)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
FormatLine(UCHAR * TBuf,sal_uInt16 & Index,ObjTextType & Atr0,ObjTextType & AktAtr,sal_uInt16 UmbWdt,sal_uInt16 AdjWdt,short * Line,sal_uInt16 & nChars,double,double,UCHAR * cLine,sal_Bool TextFit)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
DrawChar(OutputDevice & rOut,UCHAR c,ObjTextType T,PointType Pos,sal_uInt16 DrehWink,sal_uInt16 FitXMul,sal_uInt16 FitXDiv,sal_uInt16 FitYMul,sal_uInt16 FitYDiv)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 *************************************************************************/
Draw(OutputDevice & rOut)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
GetFont()1175 sal_uInt32 ObjTextType::GetFont()
1176 {
1177 return sal_uLong(FontLo)+0x00010000*sal_uLong(FontHi);
1178 }
1179
SetFont(sal_uInt32 FontID)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 /////////////////////////////////////////////////////////////////////////////////
SgfFontOne()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
ReadOne(ByteString & ID,ByteString & Dsc)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
SgfFontLst()1258 SgfFontLst::SgfFontLst()
1259 {
1260 pList=NULL;
1261 Last=NULL;
1262 LastID=0;
1263 LastLn=NULL;
1264 Tried=sal_False;
1265 }
1266
~SgfFontLst()1267 SgfFontLst::~SgfFontLst()
1268 {
1269 RausList();
1270 }
1271
RausList()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
AssignFN(const String & rFName)1289 void SgfFontLst::AssignFN(const String& rFName)
1290 { FNam=rFName; }
1291
ReadList()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
GetFontDesc(sal_uInt32 ID)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