1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sgvtext.cxx,v $
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"
35 #include <tools/config.hxx>
36 #include <svtools/filter.hxx>
37 #include "sgffilt.hxx"
38 #include "sgfbram.hxx"
39 #include "sgvmain.hxx"
42 extern SgfFontLst
* pSgfFonts
;
44 #if defined( WIN ) && defined( MSC )
45 #pragma code_seg( "SVTOOLS_FILTER1", "SVTOOLS_CODE" )
49 #define abs(x) ((x)<0 ? -(x) : (x))
53 ////////////////////////////////////////////////////////////////////////////////////////////////////
55 // Einschraenkungen: Schatten nur grau, 2D und mit fixem Abstand.
60 ////////////////////////////////////////////////////////////////////////////////////////////////////
62 /////////////////////////////////////////////////////////////////////////////////
63 /////////////////////////////////////////////////////////////////////////////////
64 /////////////////////////////////////////////////////////////////////////////////
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.
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 */
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]);
168 //==============================================================================
170 #define DefaultCharWidth 4800
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 /////////////////////////////////////////////////////////////////////////////////
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 /////////////////////////////////////////////////////////////////////////////////
238 short hPoint2Sgf(short a
)
241 b
=long(a
)*127*SgfDpmm
/(144*5);
245 short Sgf2hPoint(short a
)
248 b
=long(a
)*5*144/(127*SgfDpmm
);
253 /////////////////////////////////////////////////////////////////////////////////
254 /////////////////////////////////////////////////////////////////////////////////
255 /////////////////////////////////////////////////////////////////////////////////
259 /////////////////////////////////////////////////////////////////////////////////
260 /////////////////////////////////////////////////////////////////////////////////
261 /////////////////////////////////////////////////////////////////////////////////
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
)
274 ret
=long(MaxGrad
)*long(CharTopToBase
) /long(100);
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
)
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
='-';
316 USHORT
GetSchnittBit(UCHAR 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
;
340 long ChgValue(long Def
, long Min
, long Max
, UCHAR FlgVal
, long NumVal
)
344 if (FlgVal
==EscDeflt
) {
345 r
=Def
; // zurueck auf Default
347 if (NumVal
!=EscNoVal
) r
=NumVal
; // Hart setzen
350 if (Min
!=0 || Max
!=0) {
359 void ChgSchnittBit(USHORT Bit
, USHORT Radio1
, USHORT Radio2
, USHORT Radio3
,
360 UCHAR FlgVal
, USHORT Schnitt0
, USHORT
& Schnitt
)
364 Rad
=Radio1
| Radio2
| Radio3
;
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
)
380 while (TBuf
[Index
]==Escape
) {
383 while (TBuf
[Index
]!=Escape
&& Cnt
<=MaxEscLen
) {
392 UCHAR
ProcessOne(UCHAR
* TBuf
, USHORT
& Index
,
393 ObjTextType
& Atr0
, ObjTextType
& AktAtr
,
407 c
=TBuf
[Index
]; Index
++;
410 c
=TBuf
[Index
]; Index
++;
411 Ident
=c
; // Identifer merken
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
++; }
421 NumVal
=10*NumVal
+c
-'0';
422 EoVal
=(TBuf
[Index
]<'0' || TBuf
[Index
]>'9');
423 if (EoVal
==FALSE
) { c
=TBuf
[Index
]; Index
++; }
425 } while (i
>0 && EoVal
==FALSE
);
428 q
=!CheckTextOutl(AktAtr
.F
,AktAtr
.L
);
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;
472 if (TBuf
[Index
]==Escape
) Index
++; // zweites Esc weglesen }
474 } while (Ende
==FALSE
&& ScanEsc
==FALSE
);
475 if (Ende
==FALSE
) c
=Escape
;
477 } // end of ProcessOne
480 UCHAR
GetTextChar(UCHAR
* TBuf
, USHORT
& Index
,
481 ObjTextType
& Atr0
, ObjTextType
& AktAtr
,
482 USHORT Rest
, BOOL ScanEsc
)
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
);
491 if (Rest
==0 || Rest
==DoTrenn
||
492 nc
==' ' || nc
==AbsatzEnd
|| nc
==TextEnd
) c
='-';
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
) {
502 else if (c
=='C') c
='K';
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
)
523 c
=GetTextChar(TBuf
,Index
,Atr0
,AktAtr
,Rest
,ScanEsc
);
526 case HardSpace
: c
=' '; break;
527 case AbsatzEnd
: c
=' '; break;
528 case HardTrenn
: 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
)
554 while (!AbsEnd
&& nChar
>0) {
556 c
=GetTextChar(TBuf
,Index
,Atr0
,AktAtr
,nChar
,FALSE
);
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
;
566 if (AktAtr
.ChrVPos
>0) Grad
=Grad
-AktAtr
.ChrVPos
;
567 if (Grad
>MaxGrad
) MaxGrad
=Grad
;
570 if (!AbsEnd
&& c
!=' ') r
=i
;
572 MaxGrad
=hPoint2Sgf(MaxGrad
);
573 if (MaxLF100
<=4000) { // sonst Overflowgefahr
574 LF
=USHORT(hPoint2Sgf(short(MaxLF100
)) /100);
576 LF
=USHORT(hPoint2Sgf(short(MaxLF100
) /100));
582 // End of AbsRead.Pas
583 /////////////////////////////////////////////////////////////////////////////////
584 /////////////////////////////////////////////////////////////////////////////////
585 /////////////////////////////////////////////////////////////////////////////////
589 /////////////////////////////////////////////////////////////////////////////////
590 /////////////////////////////////////////////////////////////////////////////////
591 /////////////////////////////////////////////////////////////////////////////////
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
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
);
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
630 FNam
=String::CreateFromAscii( "Times" ); // ansonsten ist das einfach Times
633 aFont
.SetFamily(FAMILY_ROMAN
);
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
639 FNam
=String::CreateFromAscii( "Helvetica" ); // und ansonsten Helvetica
641 aFont
.SetFamily(FAMILY_SWISS
);
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
648 FNam
=String::CreateFromAscii( "Courier" ); // ansonsten ist und bleibt Courier immer Courier
650 aFont
.SetFamily(FAMILY_ROMAN
);
651 aFont
.SetPitch(PITCH_FIXED
);
653 default: FNam
=String::CreateFromAscii( "Helvetica", 9 );
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;
663 if (Atr
.Breite
!=100 || 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
))));
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
);
701 /////////////////////////////////////////////////////////////////////////////////
702 /////////////////////////////////////////////////////////////////////////////////
703 /////////////////////////////////////////////////////////////////////////////////
706 /////////////////////////////////////////////////////////////////////////////////
707 /////////////////////////////////////////////////////////////////////////////////
708 /////////////////////////////////////////////////////////////////////////////////
719 void InitProcessCharState(ProcChrSta
& State
, ObjTextType
& AktAtr
, USHORT IndexA
)
728 BOOL
UpcasePossible(UCHAR c
)
730 if ((c
>='a' && c
<='z') || c
== 0xe4 || c
== 0xf6 || c
== 0xfc ) return TRUE
;
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;
743 USHORT
GetCharWidth(OutputDevice
& rOut
, UCHAR c
)
748 c1
= ByteString::Convert((char)c
,RTL_TEXTENCODING_IBM_437
, gsl_getSystemTextEncoding() );
751 ChrWidth
=(USHORT
)rOut
.GetTextWidth( String('A') );
752 if (rOut
.GetFont().GetPitch()!=PITCH_FIXED
) {
753 ChrWidth
=MulDiv(ChrWidth
,DefaultSpace
,100);
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
));
765 ChrWidth
=(USHORT
)rOut
.GetTextWidth(String('A'));
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
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
);
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 ?
795 Temp
=ULONG(ChrWidth
)*ULONG(R
.Attrib
.ZAbst
)/100;
796 ChrWidth
=USHORT(Temp
);
799 if (R
.ChrXP
>32000) R
.ChrXP
=32000;
800 Line
[nChars
]=R
.ChrXP
-KernDist
;
802 R
.ChrXP
+=ChrWidth
-KernDist
; // Position fuer den naechsten Character
807 void FormatLine(UCHAR
* TBuf
, USHORT
& Index
, ObjTextType
& Atr0
, ObjTextType
& AktAtr
,
808 USHORT UmbWdt
, USHORT AdjWdt
,
809 short* Line
, USHORT
& nChars
,
811 UCHAR
* cLine
, BOOL TextFit
)
816 BOOL First
; // erster Char ?
817 BYTE Just
= 0; // Absatzformatierung
818 BOOL Border
; // Rand der Box erreicht ?
820 BOOL AbsEnd
; // Ende des Absatzes erreicht ?
821 ProcChrSta
* R
=new ProcChrSta
;
822 ProcChrSta
* R0
=new ProcChrSta
;
823 ProcChrSta
* WErec
=new ProcChrSta
;
825 ProcChrSta
* WErec0
=new ProcChrSta
;
827 ProcChrSta
* TRrec
=new ProcChrSta
;
830 USHORT WordEndCnt
; // Justieren und Trennen
834 short BoxRest
; // zum Quetschen und formatieren
838 vOut
.SetMapMode(MapMode(MAP_10TH_MM
,Point(),Fraction(1,4),Fraction(1,4)));
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
;
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
);
854 Just
=R
->Attrib
.Justify
& 0x0F; // Absatzformat steht wenn, dann am Anfang
856 Border
=R
->ChrXP
>UmbWdt
;
857 WordEnd
=(AbsEnd
|| (c
==' ')) && (c0
!=' ') && (c0
!=0);
859 if (WordEnd
&& !Border0
) {
864 if (Trenn
&& !Border
) {
873 AbsEnd
=AbsEnd
|| (nChars
>=MaxLineChars
);
874 } while (!(AbsEnd
|| (Border
&& ((WordEndCnt
>0) || WordEnd
|| Trenn
))));
876 if (Border
) { // Trennen und Quetschen
877 (*WErec0
)=(*WErec
); WEnChar0
=WEnChar
;
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));
890 if (WordEnd
&& (!Border0
|| (WordEndCnt
==0))) {
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
900 (*TRrec
)=(*R
); TRnChar
=nChars
; // zum weitersuchen
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);
921 Line
[nChars
+1]=UmbWdt
;
926 do { // Leerzeichen weglesen
928 c
=GetTextChar(TBuf
,R
->Index
,Atr0
,R
->Attrib
,NoTrenn
,FALSE
);
930 Line
[nChars
]=R
->ChrXP
;
933 if (c
!=' ' && c
!=AbsatzEnd
&& c
!=TextEnd
) {
939 if (AbsEnd
&& nChars
<MaxLineChars
) { // Ausrichten, statt Blocksatz aber linksbuendig
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
;
952 case THJustLeft
: break; // Links
954 BoxRest
=BoxRest
/2; // Mitte
955 for (i
=1;i
<=nChars
;i
++) Line
[i
]=Line
[i
]+BoxRest
;
957 case THJustRight
: { // Rechts
958 for (i
=1;i
<=nChars
;i
++) Line
[i
]=Line
[i
]+BoxRest
;
961 case THJustBlock
: { // Block und Austreibend
963 if (Just
==THJustDrvOut
) re
--;
964 while (re
>=1 && (cLine
[re
]==' ' || cLine
[re
]==TextEnd
|| cLine
[re
]==AbsatzEnd
)) re
--;
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
++) {
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);
982 for (i
=li
;i
<=re
;i
++) { // j Spaces aufbohren !
983 if (cLine
[i
]==' ') { // Space gefunden !
985 h
=MulDiv(k
,BoxRest
,j
);
990 for (i
=re
+1;i
<=nChars
;i
++) Line
[i
]=Line
[i
]+BoxRest
; // und den Rest anpassen
991 Line
[nChars
+1]=AdjWdt
;
993 case THJustLocked
: { //Gesperrt
995 while (re
>=1 && (cLine
[re
]==' ' || cLine
[re
]==TextEnd
|| cLine
[re
]==AbsatzEnd
)) re
--;
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
;
1017 // End of Absatz.Pas
1018 /////////////////////////////////////////////////////////////////////////////////
1019 /////////////////////////////////////////////////////////////////////////////////
1020 /////////////////////////////////////////////////////////////////////////////////
1023 /////////////////////////////////////////////////////////////////////////////////
1024 /////////////////////////////////////////////////////////////////////////////////
1025 /////////////////////////////////////////////////////////////////////////////////
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 /*************************************************************************
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 !!
1054 USHORT l
; // Anzahl der Zeichen in der Zeile
1068 BOOL LineFit
; // FitSize.x=0? oder Flags -> jede Zeile stretchen
1071 UCHAR
* cLine
; // Buffer fuer FormatLine
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;
1085 LineFit
=((Flags
& TextFitZBit
)!=0);
1086 if (TextFit
&& FitSize
.x
==0) LineFit
=TRUE
;
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;
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;
1105 xSize
=Pos2
.x
-Pos1
.x
;
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;
1115 T2
=T1
; Index2
=Index1
;
1116 FormatLine(Buf
,Index2
,T
,T2
,xSize
,xSAdj
,xLine
,l
,sn
,cs
,cLine
,LineFit
);
1117 Fehler
=(Index2
==Index1
);
1119 lc
=GetLineFeed(Buf
,Index1
,T
,T1
,l
,LF
,MaxGrad
);
1121 if (LineFit
) FitXDiv
=xLine
[lc
+1];
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
);
1131 FitXDiv
=1; // 0 gibts nicht
1135 TopToBase
=GetTopToBaseLine(MaxGrad
);
1136 yPos
=yPos
+TopToBase
;
1137 Ende
=(yPos0
+short(MulDiv(MaxGrad
,CharTopToBtm
,100))>ySize
) && !TextFit
;
1139 T2
=T1
; Index2
=Index1
;
1142 c
=GetTextCharConv(Buf
,Index2
,T
,T2
,l
-i
,FALSE
);
1143 long xp1
,yp1
; // wegen Overflowgefahr
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;
1152 if (DrehWink
!=0) RotatePoint(Pos
,Pos1
.x
,Pos1
.y
,sn
,cs
);
1153 DrawChar(rOut
,c
,T2
,Pos
,DrehWink
,FitXMul
,FitXDiv
,FitYMul
,FitYDiv
);
1157 T1
=T2
; Index1
=Index2
; // Fuer die naechste Zeile
1158 } // if ObjMin.y+yPos<=Obj_Max.y
1160 } while (c
!=TextEnd
&& !Ende
&& !Fehler
);
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()
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()
1210 SVFamil
=FAMILY_DONTKNOW
;
1211 SVChSet
=RTL_TEXTENCODING_DONTKNOW
;
1215 void SgfFontOne::ReadOne( ByteString
& ID
, ByteString
& Dsc
)
1220 if ( Dsc
.Len() < 4 || ( Dsc
.GetChar( 0 ) != '(' ) )
1222 i
=1; // Erster Buchstabe des IF-Fontnamen. Davor ist eine '('
1223 while ( i
< Dsc
.Len() && ( Dsc
.GetChar( i
) !=')' ) )
1225 Dsc
.Erase(0,i
+1); // IF-Fontname loeschen inkl. ()
1227 if ( Dsc
.Len() < 2 || ( Dsc
.GetChar( Dsc
.Len() - 1 ) !=')' ) )
1229 i
=Dsc
.Len()-2; // hier ist die ')' des SV-Fontnames
1231 while ( i
> 0 && ( Dsc
.GetChar( i
) != '(' ) )
1236 SVFName
=String(Dsc
,i
+1,j
); // SV-Fontname rausholen
1239 IFID
= (UINT32
)ID
.ToInt32();
1240 n
=Dsc
.GetTokenCount(' ');
1243 s
= Dsc
.GetToken( i
,' ' );
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()
1278 SgfFontLst::~SgfFontLst()
1283 void SgfFontLst::RausList()
1300 void SgfFontLst::AssignFN(const String
& rFName
)
1303 void SgfFontLst::ReadList()
1311 aCfg
.SetGroup("SGV Fonts fuer StarView");
1312 USHORT Anz
=aCfg
.GetKeyCount();
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
)
1336 while (P
!=NULL
&& P
->IFID
!=ID
) P
=P
->Next
;