1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include <boost/static_assert.hpp>
24 #include <comphelper/string.hxx>
25 #include <tools/config.hxx>
26 #include <vcl/graphicfilter.hxx>
27 #include "sgffilt.hxx"
28 #include "sgfbram.hxx"
29 #include "sgvmain.hxx"
31 extern SgfFontLst
* pSgfFonts
;
34 #define abs(x) ((x)<0 ? -(x) : (x))
38 ////////////////////////////////////////////////////////////////////////////////////////////////////
40 // Einschraenkungen: Schatten nur grau, 2D und mit fixem Abstand.
45 ////////////////////////////////////////////////////////////////////////////////////////////////////
47 /////////////////////////////////////////////////////////////////////////////////
48 /////////////////////////////////////////////////////////////////////////////////
49 /////////////////////////////////////////////////////////////////////////////////
52 // vvv Sonderzeichen im TextBuffer vvv
53 #define TextEnd 0 /* ^@ Ende der Zeichenkette */
54 #define HardSpace 6 /* ^F Hartspace (wird nicht umbrochen) ,' ' */
55 #define SoftTrennK 11 /* ^K Zeichen fuer k-c-Austausch bei Trennung, 'k' */
56 #define AbsatzEnd 13 /* ^M Neuer Absatz =CR */
57 #define HardTrenn 16 /* ^P Hartes Trennzeichen (wird nicht umbrochen), '-' */
58 #define SoftTrennAdd 19 /* ^S Zusatz-Zeichen Trennung von z.b."Schiff-fahrt" */
59 #define Escape 27 /* ^[ Escapesequenz einleiten */
60 #define SoftTrenn 31 /* ^_ Weiches Trennzeichen, '-' nur Zeilenende */
61 #define MaxEscValLen 8
62 #define MaxEscLen (MaxEscValLen+3)
64 //==============================================================================
65 // Escapesequenzen: [Esc]<Ident><Value>[Esc] also mind. 4 Char
66 // Max. Laenge von Value soll sein: 8 Char (7+Vorzeichen). Demnach max. Laenge
67 // einer Escapesequenz: 11 Char.
70 #define EscFont 'F' /* FontID, z.B. 92500 fuer CG Times */
71 #define EscGrad 'G' /* Schriftgrad 1..255 fuer <<Pt-127<<Pt */
72 #define EscBreit 'B' /* Breite 1..255% des Schriftgrades */
73 #define EscKaptS 'K' /* Kapitaelchengroesse 1..255% des Schriftgrades */
74 #define EscLFeed 'L' /* Zeilenabstand 1..32767% vom max. Schriftgrad der Zeile */
75 // oder 1..32767 fuer 1..16383<<Pt absolut (Wenn Bit 15=1)
76 #define EscSlant 'S' /* Kursiv(Winkel) 1..8999 fuer 0.01deg..89.99deg */
77 #define EscVPos 'V' /* Zeichen Vertikal-Position 1..255 fuer <<Pt..127<<Pt */
78 #define EscZAbst 'Z' /* Zeichenabstand -128..127% */
79 #define EscHJust 'A' /* H-Justify Absatz: Links, Zentr, Rechts, Block, Austreibend, Gesperrt (0..5)*/
81 #define EscFarbe 'C' /* Farbe 0..7 */
82 #define EscBFarb 'U' /* BackFarbe 0..7 */
83 #define EscInts 'I' /* Farbintensitaet 0..100% */
84 #define EscMustr 'M' /* Muster 0..? inkl. Transp... */
85 #define EscMFarb 'O' /* Musterfarbe 0..7 */
86 #define EscMBFrb 'P' /* 2. Musterfarbe 0..7 */
87 #define EscMInts 'W' /* Musterintensitaet 0..7 */
89 #define EscSMstr 'E' /* Schattenmuster 0..? inkl. Transp... */
90 #define EscSFarb 'R' /* Schattenfarbe 0..7 */
91 #define EscSBFrb 'T' /* 2. Schattenfarbe 0..7 */
92 #define EscSInts 'Q' /* Schattenintensitaet 0..7 */
94 #define EscSXDst 'X' /* Schattenversatz X 0..100% */
95 #define EscSYDst 'Y' /* Schattenversatz Y 0..100% */
96 #define EscSDist 'D' /* Schattenversatz X-Y 0..100% */
98 #define EscBold 'f' /* Fett */
99 #define EscLSlnt 'l' /* LKursiv */
100 #define EscRSlnt 'r' /* RKursiv */
101 #define EscUndln 'u' /* Unterstrichen */
102 #define EscDbUnd 'p' /* doppelt Unterstrichen */
103 #define EscKaptF 'k' /* Kapitaelchenflag */
104 #define EscStrik 'd' /* Durchgestrichen */
105 #define EscDbStk 'e' /* doppelt Durchgestrichen */
106 #define EscSupSc 'h' /* Hochgestellt */
107 #define EscSubSc 't' /* Tiefgestellt */
108 #define Esc2DShd 's' /* 2D-Schatten */
109 #define Esc3DShd 'j' /* 3D-Schatten */
110 #define Esc4DShd 'i' /* 4D-Schatten */
111 #define EscEbShd 'b' /* Embossed */
113 // AllEscIdent =[EscFont, EscGrad, EscBreit,EscKaptS,EscLFeed,EscSlant,EscVPos, EscZAbst,EscHJust,
114 // EscFarbe,EscBFarb,EscInts, EscMustr,EscMFarb,EscMBFrb,EscMInts,
115 // EscSMstr,EscSFarb,EscSBFrb,EscSInts,EscSXDst,EscSYDst,EscSDist,
116 // EscBold, EscLSlnt,EscRSlnt,EscUndln,EscDbUnd,EscKaptF,EscStrik,EscDbStk,
117 // EscSupSc,EscSubSc,Esc2DShd,Esc3DShd,Esc4DShd];
118 // Justify muss spaetestens am Anfang des Absatzes stehen
119 #define EscSet '\x1e' /* Flag setzen */
120 #define EscReset '\x1f' /* Flag loeschen */
121 #define EscDeflt '\x11' /* Flag auf default setzen */
122 #define EscToggl '\x1d' /* Flag Toggeln */
124 #define EscNoVal -2147483647 /* -MaxLongInt */
125 //==============================================================================
126 #define NoTrenn 0xFFFF /* Wert fuer Parameter 'Rest' von GetTextChar(), wenn auf keinen Fall getrennt werden soll */
127 #define DoTrenn 0xFFFE /* Wert fuer Parameter 'Rest' von GetTextChar(), wenn getrennt werden soll */
129 #define MaxLineChars 1024
131 #define ChrXPosArrSize (MaxLineChars+1+1) /* 2k - Beginnt mit 0 im gegensatz zu StarDraw */
132 #define CharLineSize (MaxLineChars+1+1)
138 //==============================================================================
140 #define CharTopToBase 100 /* wegen Apostrophe und Umlaute mehr als 75% */
141 #define CharTopToBtm 120 /* Zeilenhoehe ist groesser als Schriftgrad */
142 // bei Avanti-Bold 'ue' eigentlich sogar 130%
144 // end of AbsBase.Pas
145 /////////////////////////////////////////////////////////////////////////////////
146 /////////////////////////////////////////////////////////////////////////////////
147 /////////////////////////////////////////////////////////////////////////////////
151 /////////////////////////////////////////////////////////////////////////////////
152 /////////////////////////////////////////////////////////////////////////////////
153 /////////////////////////////////////////////////////////////////////////////////
156 #define TextBoldBit 0x0001 /* Fett */
157 #define TextRSlnBit 0x0002 /* Kursiv */
158 #define TextUndlBit 0x0004 /* Unterstrichen */
159 #define TextStrkBit 0x0008 /* Durchgesteichen */
160 #define TextSupSBit 0x0010 /* Hocgestellt */
161 #define TextSubSBit 0x0020 /* Tiefgestellt */
162 #define TextKaptBit 0x0040 /* Kapitaelchen */
163 #define TextLSlnBit 0x0080 /* Linkskursiv */
164 #define TextDbUnBit 0x0100 /* Doppelt unterstrichen */
165 #define TextDbStBit 0x0200 /* Doppelt durchgestrichen */
166 #define TextSh2DBit 0x0400 /* 2D-Schatten 2.0 */
167 #define TextSh3DBit 0x0800 /* 3D-Schatten 2.0 */
168 #define TextSh4DBit 0x1000 /* 4D-Schatten 2.0 */
169 #define TextShEbBit 0x2000 /* Embossed-Schatten 2.0 */
171 #define THJustLeft 0x00
172 #define THJustCenter 0x01
173 #define THJustRight 0x02
174 #define THJustBlock 0x03
175 #define THJustDrvOut 0x04 /* Austreibend Formatiert */
176 #define THJustLocked 0x05 /* A l s S p e r r s c h r i f t */
178 #define MaxCharSlant 4200 /* Maximal 42deg kursiv ! */
180 // end of DefBase.Pas
181 /////////////////////////////////////////////////////////////////////////////////
182 /////////////////////////////////////////////////////////////////////////////////
183 /////////////////////////////////////////////////////////////////////////////////
186 sal_Bool
CheckTextOutl(ObjAreaType
& F
, ObjLineType
& L
);
188 sal_Bool
CheckTextOutl(ObjAreaType
& F
, ObjLineType
& L
)
190 return (F
.FIntens
!=L
.LIntens
) ||
191 ((F
.FFarbe
!=L
.LFarbe
) && (F
.FIntens
>0)) ||
192 ((F
.FBFarbe
!=L
.LBFarbe
) && (F
.FIntens
<100));
196 /////////////////////////////////////////////////////////////////////////////////
197 /////////////////////////////////////////////////////////////////////////////////
198 /////////////////////////////////////////////////////////////////////////////////
201 short hPoint2Sgf(short a
)
204 b
=long(a
)*127*SgfDpmm
/(144*5);
211 // ======================================================================
212 // Function GetTopToBaseLine() Function GetBaseLineToBtm()
214 // Abstand von Zeilenoberkante bis BaseLine bzw. von BaseLine bis
215 // Unterkante berechnen. Alles in SGF-Units.
216 // ======================================================================
218 sal_uInt16
GetTopToBaseLine(sal_uInt16 MaxGrad
)
221 ret
=long(MaxGrad
)*long(CharTopToBase
) /long(100);
222 return sal_uInt16(ret
);
225 // ======================================================================
226 // Function GetTextChar() Function GetTextCharConv()
228 // Liest ein Zeichen aus dem Textbuffer, wertet dabei eventuell
229 // auftretende Escapesequenzen aus und setzt dementsprechend den
230 // Ein-/Ausgabeparameter AktAtr. Index wird entsprechend erhoeht.
231 // Der Parameter Rest muss immer die Anzahl der Zeichen beinhalten,
232 // den angeforderten Zeichen in der aktuellen Zeile noch folgen.
233 // Ansonsten funktioniert die Silbentrennung nicht richtig. Gibt man
234 // stattdessen die Konstante NoTrenn an, wird in keinem Fall
235 // getrennt, die Konstante DoTrenn bewirkt dagegen, dass ueberall dort
236 // getrennt wird, wo ein SoftTrenner vorkommt.
238 // SoftTrenner werden immer in ein Minuszeichen konvertiert.
239 // GetTextCharConv() konvertiert zusaetzlich HardSpace und AbsatzEnde
240 // in Spaces sowie HardTrenner in Minuszeichen. TextEnde wird immer
241 // als Char(0) geliefert.
242 // ======================================================================
246 UCHAR
ConvertTextChar(UCHAR c
)
250 case HardSpace
: c
=' '; break;
251 case AbsatzEnd
: c
=' '; break;
252 case SoftTrenn
: c
='-'; break;
253 case HardTrenn
: c
='-'; break;
254 case SoftTrennK
: c
='-'; break;
255 case SoftTrennAdd
: c
='-';
261 long ChgValue(long Def
, long Min
, long Max
, UCHAR FlgVal
, long NumVal
)
265 if (FlgVal
==EscDeflt
) {
266 r
=Def
; // zurueck auf Default
268 if (NumVal
!=EscNoVal
) r
=NumVal
; // Hart setzen
271 if (Min
!=0 || Max
!=0) {
280 void ChgSchnittBit(sal_uInt16 Bit
, sal_uInt16 Radio1
, sal_uInt16 Radio2
, sal_uInt16 Radio3
,
281 UCHAR FlgVal
, sal_uInt16 Schnitt0
, sal_uInt16
& Schnitt
)
285 Rad
=Radio1
| Radio2
| Radio3
;
289 case EscSet
: Schnitt
=(Schnitt
& ~All
) | Bit
; break;
290 case EscReset
: Schnitt
=(Schnitt
& ~All
); break;
291 case EscDeflt
: Schnitt
=(Schnitt
& ~All
) | (Schnitt0
& All
); break;
292 case EscToggl
: Schnitt
=(Schnitt
& ~Rad
) ^ Bit
;
298 UCHAR
GetNextChar(UCHAR
* TBuf
, sal_uInt16 Index
)
301 while (TBuf
[Index
]==Escape
) {
304 while (TBuf
[Index
]!=Escape
&& Cnt
<=MaxEscLen
) {
313 UCHAR
ProcessOne(UCHAR
* TBuf
, sal_uInt16
& Index
,
314 ObjTextType
& Atr0
, ObjTextType
& AktAtr
,
328 c
=TBuf
[Index
]; Index
++;
330 if (Ende
==sal_False
) {
331 c
=TBuf
[Index
]; Index
++;
332 Ident
=c
; // Identifer merken
335 c
=TBuf
[Index
]; Index
++; // Hier faengt der Wert an
336 if (c
==EscSet
|| c
==EscReset
|| c
==EscDeflt
|| c
==EscToggl
) FlgVal
=c
; else {
337 if (c
=='-') Sgn
=-1; else Sgn
=1;
338 if (c
=='+' || c
=='-') { c
=TBuf
[Index
]; Index
++; }
342 NumVal
=10*NumVal
+c
-'0';
343 EoVal
=(TBuf
[Index
]<'0' || TBuf
[Index
]>'9');
344 if (EoVal
==sal_False
) { c
=TBuf
[Index
]; Index
++; }
346 } while (i
>0 && EoVal
==sal_False
);
349 q
=!CheckTextOutl(AktAtr
.F
,AktAtr
.L
);
352 case EscFont
: AktAtr
.SetFont(sal_uLong (ChgValue(Atr0
.GetFont(),0,0 ,FlgVal
,NumVal
)));break;
353 case EscGrad
: AktAtr
.Grad
=sal_uInt16(ChgValue(Atr0
.Grad
, 2,2000 ,FlgVal
,NumVal
)); break;
354 case EscBreit
: AktAtr
.Breite
=sal_uInt16(ChgValue(Atr0
.Breite
, 1,1000 ,FlgVal
,NumVal
)); break;
355 case EscKaptS
: AktAtr
.Kapit
=(sal_uInt8
)(ChgValue(Atr0
.Kapit
, 1,255 ,FlgVal
,NumVal
)); break;
356 case EscLFeed
: AktAtr
.LnFeed
=sal_uInt16(ChgValue(Atr0
.LnFeed
, 1,65535 ,FlgVal
,NumVal
)); break;
357 case EscSlant
: AktAtr
.Slant
=sal_uInt16(ChgValue(Atr0
.Slant
, 1,MaxCharSlant
,FlgVal
,NumVal
)); break;
358 case EscVPos
: AktAtr
.ChrVPos
=char (ChgValue(Atr0
.ChrVPos
,-128,127 ,FlgVal
,NumVal
)); break;
359 case EscZAbst
: AktAtr
.ZAbst
=(sal_uInt8
)(ChgValue(Atr0
.ZAbst
, 1,255 ,FlgVal
,NumVal
)); break;
360 case EscHJust
: AktAtr
.Justify
=(sal_uInt8
)(ChgValue(Atr0
.Justify
& 0x0F,0,5 ,FlgVal
,NumVal
)); break;
361 case EscFarbe
: { AktAtr
.L
.LFarbe
=(sal_uInt8
)(ChgValue(Atr0
.L
.LFarbe
,0,7 ,FlgVal
,NumVal
)); if (q
) AktAtr
.F
.FFarbe
=AktAtr
.L
.LFarbe
; } break;
362 case EscBFarb
: { AktAtr
.L
.LBFarbe
=(sal_uInt8
)(ChgValue(Atr0
.L
.LBFarbe
,0,255,FlgVal
,NumVal
)); if (q
) AktAtr
.F
.FBFarbe
=AktAtr
.L
.LBFarbe
; } break;
363 case EscInts
: { AktAtr
.L
.LIntens
=(sal_uInt8
)(ChgValue(Atr0
.L
.LIntens
,0,100,FlgVal
,NumVal
)); if (q
) AktAtr
.F
.FIntens
=AktAtr
.L
.LIntens
; } break;
365 case EscMustr
: { AktAtr
.F
.FMuster
=sal_uInt16(ChgValue(Atr0
.F
.FMuster
,0,65535,FlgVal
,NumVal
)); } break;
366 case EscMFarb
: { AktAtr
.F
.FFarbe
=(sal_uInt8
)(ChgValue(Atr0
.F
.FFarbe
,0,7 ,FlgVal
,NumVal
)); } break;
367 case EscMBFrb
: { AktAtr
.F
.FBFarbe
=(sal_uInt8
)(ChgValue(Atr0
.F
.FBFarbe
,0,255,FlgVal
,NumVal
)); } break;
368 case EscMInts
: { AktAtr
.F
.FIntens
=(sal_uInt8
)(ChgValue(Atr0
.F
.FIntens
,0,100,FlgVal
,NumVal
)); } break;
370 case EscSMstr
: { AktAtr
.ShdF
.FMuster
=sal_uInt16(ChgValue(Atr0
.ShdF
.FMuster
,0,65535,FlgVal
,NumVal
)); } break;
371 case EscSFarb
: { AktAtr
.ShdL
.LFarbe
=(sal_uInt8
)(ChgValue(Atr0
.ShdL
.LFarbe
,0,7 ,FlgVal
,NumVal
)); AktAtr
.ShdF
.FFarbe
=AktAtr
.ShdL
.LFarbe
; } break;
372 case EscSBFrb
: { AktAtr
.ShdL
.LBFarbe
=(sal_uInt8
)(ChgValue(Atr0
.ShdL
.LBFarbe
,0,255,FlgVal
,NumVal
)); AktAtr
.ShdF
.FBFarbe
=AktAtr
.ShdL
.LBFarbe
; } break;
373 case EscSInts
: { AktAtr
.ShdL
.LIntens
=(sal_uInt8
)(ChgValue(Atr0
.ShdL
.LIntens
,0,100,FlgVal
,NumVal
)); AktAtr
.ShdF
.FIntens
=AktAtr
.ShdL
.LIntens
; } break;
374 case EscSDist
: { AktAtr
.ShdVers
.x
=(short)ChgValue(Atr0
.ShdVers
.x
,0,30000,FlgVal
,NumVal
); AktAtr
.ShdVers
.y
=AktAtr
.ShdVers
.x
; } break;
375 case EscSXDst
: { AktAtr
.ShdVers
.x
=(short)ChgValue(Atr0
.ShdVers
.x
,0,30000,FlgVal
,NumVal
); } break;
376 case EscSYDst
: { AktAtr
.ShdVers
.y
=(short)ChgValue(Atr0
.ShdVers
.y
,0,30000,FlgVal
,NumVal
); } break;
378 case EscBold
: ChgSchnittBit(TextBoldBit
,0,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
379 case EscRSlnt
: ChgSchnittBit(TextRSlnBit
,TextLSlnBit
,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
380 case EscUndln
: ChgSchnittBit(TextUndlBit
,TextDbUnBit
,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
381 case EscStrik
: ChgSchnittBit(TextStrkBit
,TextDbStBit
,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
382 case EscDbUnd
: ChgSchnittBit(TextDbUnBit
,TextUndlBit
,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
383 case EscDbStk
: ChgSchnittBit(TextDbStBit
,TextStrkBit
,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
384 case EscSupSc
: ChgSchnittBit(TextSupSBit
,TextSubSBit
,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
385 case EscSubSc
: ChgSchnittBit(TextSubSBit
,TextSupSBit
,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
386 case EscKaptF
: ChgSchnittBit(TextKaptBit
,0,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
387 case EscLSlnt
: ChgSchnittBit(TextLSlnBit
,TextRSlnBit
,0,0 ,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
388 case Esc2DShd
: ChgSchnittBit(TextSh2DBit
,TextSh3DBit
,TextSh4DBit
,TextShEbBit
,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
389 case Esc3DShd
: ChgSchnittBit(TextSh3DBit
,TextSh2DBit
,TextSh4DBit
,TextShEbBit
,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
390 case Esc4DShd
: ChgSchnittBit(TextSh4DBit
,TextSh2DBit
,TextSh3DBit
,TextShEbBit
,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
391 case EscEbShd
: ChgSchnittBit(TextShEbBit
,TextSh2DBit
,TextSh3DBit
,TextSh4DBit
,FlgVal
,Atr0
.Schnitt
,AktAtr
.Schnitt
); break;
393 if (TBuf
[Index
]==Escape
) Index
++; // zweites Esc weglesen }
394 } // if Ende==sal_False
395 } while (Ende
==sal_False
&& ScanEsc
==sal_False
);
396 if (Ende
==sal_False
) c
=Escape
;
398 } // end of ProcessOne
401 UCHAR
GetTextChar(UCHAR
* TBuf
, sal_uInt16
& Index
,
402 ObjTextType
& Atr0
, ObjTextType
& AktAtr
,
403 sal_uInt16 Rest
, sal_Bool ScanEsc
)
407 c
=ProcessOne(TBuf
,Index
,Atr0
,AktAtr
,ScanEsc
);
408 if (ScanEsc
==sal_False
) {
409 if (c
==SoftTrennAdd
|| c
==SoftTrennK
|| c
==SoftTrenn
) {
410 nc
=GetNextChar(TBuf
,Index
);
412 if (Rest
==0 || Rest
==DoTrenn
||
413 nc
==' ' || nc
==AbsatzEnd
|| nc
==TextEnd
) c
='-';
415 c
=ProcessOne(TBuf
,Index
,Atr0
,AktAtr
,ScanEsc
); // den Trenner ueberspringen
416 if (c0
==SoftTrennAdd
) {
417 if (c
>=32) c
=ProcessOne(TBuf
,Index
,Atr0
,AktAtr
,ScanEsc
); // und hier noch 'nen Buchstaben ueberspringen
421 if ((Rest
==1 || Rest
==DoTrenn
) && GetNextChar(TBuf
,Index
)==SoftTrennK
) {
423 else if (c
=='C') c
='K';
429 // HardSpace und HardTrenn muessen explizit konvertiert werden ! }
430 // if AktAtr.Schnitt and TextKaptBit =TextKaptBit then c:=UpCase(c);(explizit) }
432 // Bei der Trennmethode SoftTrennAdd wird davon ausgegangen, dass der zu }
433 // trennende Konsonant bereits 3x mal im TextBuf vorhanden ist, z.b.: }
434 // "Schiff-fahrt". Wenn nicht getrennt, dann wird "-f" entfernt. }
438 UCHAR
GetTextCharConv(UCHAR
* TBuf
, sal_uInt16
& Index
,
439 ObjTextType
& Atr0
, ObjTextType
& AktAtr
,
440 sal_uInt16 Rest
, sal_Bool ScanEsc
)
444 c
=GetTextChar(TBuf
,Index
,Atr0
,AktAtr
,Rest
,ScanEsc
);
447 case HardSpace
: c
=' '; break;
448 case AbsatzEnd
: c
=' '; break;
449 case HardTrenn
: c
='-';
456 // ======================================================================
457 // Function GetLineFeed()
459 // Benoetigter Zeilenabstand in SGF-Units. ChrVPos wird beruecksichtigt.
460 // ======================================================================
461 sal_uInt16
GetLineFeed(UCHAR
* TBuf
, sal_uInt16 Index
, ObjTextType Atr0
, ObjTextType AktAtr
,
462 sal_uInt16 nChar
, sal_uInt16
& LF
, sal_uInt16
& MaxGrad
)
465 sal_Bool AbsEnd
=sal_False
;
467 sal_uLong MaxLF100
=0;
469 sal_Bool First
=sal_True
;
475 while (!AbsEnd
&& nChar
>0) {
477 c
=GetTextChar(TBuf
,Index
,Atr0
,AktAtr
,nChar
,sal_False
);
479 AbsEnd
=(c
==TextEnd
|| c
==AbsatzEnd
);
480 if (First
|| (!AbsEnd
&& c
!=' ' && c
!=HardTrenn
)) {
481 LFauto
=(AktAtr
.LnFeed
& 0x8000)==0;
482 LF100
=AktAtr
.LnFeed
& 0x7FFF;
483 if (LFauto
) LF100
=LF100
*AktAtr
.Grad
; else LF100
*=LF100
;
484 if (AktAtr
.ChrVPos
>0) LF100
-=AktAtr
.ChrVPos
*100;
485 if (LF100
>MaxLF100
) MaxLF100
=LF100
;
487 if (AktAtr
.ChrVPos
>0) Grad
=Grad
-AktAtr
.ChrVPos
;
488 if (Grad
>MaxGrad
) MaxGrad
=Grad
;
491 if (!AbsEnd
&& c
!=' ') r
=i
;
493 MaxGrad
=hPoint2Sgf(MaxGrad
);
494 if (MaxLF100
<=4000) { // sonst Overflowgefahr
495 LF
=sal_uInt16(hPoint2Sgf(short(MaxLF100
)) /100);
497 LF
=sal_uInt16(hPoint2Sgf(short(MaxLF100
) /100));
503 // End of AbsRead.Pas
504 /////////////////////////////////////////////////////////////////////////////////
505 /////////////////////////////////////////////////////////////////////////////////
506 /////////////////////////////////////////////////////////////////////////////////
510 /////////////////////////////////////////////////////////////////////////////////
511 /////////////////////////////////////////////////////////////////////////////////
512 /////////////////////////////////////////////////////////////////////////////////
515 #define SuperSubFact 60 /* SuperScript/SubScript: 60% vom Schriftgrad */
516 #define DefaultSpace 40 /* Default: Space ist 40% vom SchriftGrad */
518 sal_uInt16
SetTextContext(OutputDevice
& rOut
, ObjTextType
& Atr
, sal_Bool Kapt
, sal_uInt16 Dreh
,
519 sal_uInt16 FitXMul
, sal_uInt16 FitXDiv
, sal_uInt16 FitYMul
, sal_uInt16 FitYDiv
)
521 SgfFontOne
* pSgfFont
; // Font aus dem IniFile
527 sal_uInt16 StdBrei
=50; // Durchschnittliche Zeichenbreite in % von Schriftgrad
528 sal_Bool bFit
=(FitXMul
!=1 || FitXDiv
!=1 || FitYMul
!=1 || FitYDiv
!=1);
530 pSgfFont
= pSgfFonts
->GetFontDesc(Atr
.GetFont());
532 if ( pSgfFont
!=NULL
)
534 FNam
=pSgfFont
->SVFName
;
535 StdBrei
=pSgfFont
->SVWidth
;
536 if (pSgfFont
->Fixd
) aFont
.SetPitch(PITCH_FIXED
); else aFont
.SetPitch(PITCH_VARIABLE
);
537 aFont
.SetFamily(pSgfFont
->SVFamil
);
538 aFont
.SetCharSet(pSgfFont
->SVChSet
);
542 { // Falls nich im Inifile, sind hier einige Fonts hart kodiert
543 aFont
.SetPitch(PITCH_VARIABLE
);
544 switch (Atr
.GetFont()) {
545 case 92500: case 92501: case 92504: case 92505:
548 FNam
=OUString("Times New Roman"); // CG Times ist unter Windows Times New Roman
550 FNam
=OUString("Times"); // ansonsten ist das einfach Times
553 aFont
.SetFamily(FAMILY_ROMAN
);
555 case 94021: case 94022: case 94023: case 94024: {
557 FNam
=OUString("Arial"); // Univers ist unter Windows Arial
559 FNam
=OUString("Helvetica"); // und ansonsten Helvetica
561 aFont
.SetFamily(FAMILY_SWISS
);
564 case 93950: case 93951: case 93952: case 93953: {
566 FNam
=OUString("Courier New"); // Der Vector-Courierfont unter Windows heisst Courier New
568 FNam
=OUString("Courier"); // ansonsten ist und bleibt Courier immer Courier
570 aFont
.SetFamily(FAMILY_ROMAN
);
571 aFont
.SetPitch(PITCH_FIXED
);
573 default: FNam
= OUString("Helvetica");
576 //aFont.SetCharSet(CHARSET_SYSTEM);
579 Grad
=sal_uLong(Atr
.Grad
);
580 if ((Atr
.Schnitt
& TextKaptBit
) !=0 && Kapt
) Grad
=Grad
*sal_uLong(Atr
.Kapit
)/100;
581 if ((Atr
.Schnitt
& TextSupSBit
) !=0 || (Atr
.Schnitt
& TextSubSBit
) !=0) Grad
=Grad
*SuperSubFact
/100;
583 if (Atr
.Breite
!=100 || bFit
) {
585 Grad
=Grad
*sal_uLong(FitYMul
)/sal_uLong(FitYDiv
);
586 Brei
=Brei
*sal_uLong(FitXMul
)/sal_uLong(FitXDiv
);
588 Brei
=Brei
*sal_uLong(Atr
.Breite
)/100;
589 Brei
=Brei
*sal_uLong(StdBrei
)/100;
590 aFont
.SetSize(Size(hPoint2Sgf(sal_uInt16(Brei
)),hPoint2Sgf(sal_uInt16(Grad
))));
592 aFont
.SetSize(Size(0,hPoint2Sgf(sal_uInt16(Grad
))));
595 aColor
=Sgv2SvFarbe(Atr
.L
.LFarbe
,Atr
.L
.LBFarbe
,Atr
.L
.LIntens
); aFont
.SetColor(aColor
);
596 aColor
=Sgv2SvFarbe(Atr
.F
.FFarbe
,Atr
.F
.FBFarbe
,Atr
.F
.FIntens
); aFont
.SetFillColor(aColor
);
597 aFont
.SetTransparent(sal_True
);
598 aFont
.SetAlign(ALIGN_BASELINE
);
600 Dreh
/=10; Dreh
=3600-Dreh
; if (Dreh
==3600) Dreh
=0;
601 aFont
.SetOrientation(Dreh
);
603 if ((Atr
.Schnitt
& TextBoldBit
) !=0) aFont
.SetWeight(WEIGHT_BOLD
);
604 if ((Atr
.Schnitt
& TextRSlnBit
) !=0) aFont
.SetItalic(ITALIC_NORMAL
);
605 if ((Atr
.Schnitt
& TextUndlBit
) !=0) aFont
.SetUnderline(UNDERLINE_SINGLE
);
606 if ((Atr
.Schnitt
& TextDbUnBit
) !=0) aFont
.SetUnderline(UNDERLINE_DOUBLE
);
607 if ((Atr
.Schnitt
& TextStrkBit
) !=0) aFont
.SetStrikeout(STRIKEOUT_SINGLE
);
608 if ((Atr
.Schnitt
& TextDbStBit
) !=0) aFont
.SetStrikeout(STRIKEOUT_DOUBLE
);
609 if ((Atr
.Schnitt
& TextSh2DBit
) !=0) aFont
.SetShadow(sal_True
);
610 if ((Atr
.Schnitt
& TextSh3DBit
) !=0) aFont
.SetShadow(sal_True
);
611 if ((Atr
.Schnitt
& TextSh4DBit
) !=0) aFont
.SetShadow(sal_True
);
612 if ((Atr
.Schnitt
& TextShEbBit
) !=0) aFont
.SetShadow(sal_True
);
613 if (CheckTextOutl(Atr
.F
,Atr
.L
)) aFont
.SetOutline(sal_True
);
615 if (aFont
!=rOut
.GetFont()) rOut
.SetFont(aFont
);
621 /////////////////////////////////////////////////////////////////////////////////
622 /////////////////////////////////////////////////////////////////////////////////
623 /////////////////////////////////////////////////////////////////////////////////
626 /////////////////////////////////////////////////////////////////////////////////
627 /////////////////////////////////////////////////////////////////////////////////
628 /////////////////////////////////////////////////////////////////////////////////
639 void InitProcessCharState(ProcChrSta
& State
, ObjTextType
& AktAtr
, sal_uInt16 IndexA
)
645 State
.Kapt
=sal_False
;
648 sal_Bool
UpcasePossible(UCHAR c
)
650 if ((c
>='a' && c
<='z') || c
== 0xe4 || c
== 0xf6 || c
== 0xfc ) return sal_True
;
651 else return sal_False
;
654 UCHAR
Upcase(UCHAR c
)
656 if ((c
>=(UCHAR
)'a' && c
<=(UCHAR
)'z')) c
=(c
-(UCHAR
)'a')+(UCHAR
)'A';
657 else if ( c
== 0xe4 ) c
= 0xc4;
658 else if ( c
== 0xf6 ) c
= 0xd6;
659 else if ( c
== 0xfc ) c
= 0xdc;
663 sal_uInt16
GetCharWidth(OutputDevice
& rOut
, UCHAR c
)
669 ChrWidth
=(sal_uInt16
)rOut
.GetTextWidth( OUString('A') );
670 if (rOut
.GetFont().GetPitch()!=PITCH_FIXED
) {
671 ChrWidth
=MulDiv(ChrWidth
,DefaultSpace
,100);
676 // with MaxChar == 255 c cannot be greater than MaxChar
677 // assert if MaxChar is ever changed
678 BOOST_STATIC_ASSERT( MaxChar
== 255 );
679 BOOST_STATIC_ASSERT(sizeof(UCHAR
) == 1);
680 if (c
>=MinChar
/*&& c<=MaxChar*/)
682 ChrWidth
=(sal_uInt16
)rOut
.GetTextWidth(OUString(reinterpret_cast<sal_Char
*>(&c
), 1, RTL_TEXTENCODING_IBM_437
));
686 ChrWidth
=(sal_uInt16
)rOut
.GetTextWidth(OUString(static_cast<sal_Unicode
>('A')));
692 UCHAR
ProcessChar(OutputDevice
& rOut
, UCHAR
* TBuf
, ProcChrSta
& R
, ObjTextType
& Atr0
,
693 sal_uInt16
& nChars
, sal_uInt16 Rest
,
694 short* Line
, UCHAR
* cLine
)
696 sal_uInt16 KernDist
=0; // Wert fuer Kerning
702 c
=GetTextChar(TBuf
,R
.Index
,Atr0
,R
.Attrib
,Rest
,sal_False
); // versucht evtl. zu trennen, wenn Rest entsprechenden Wert besitzt
704 AbsEnd
=(c
==AbsatzEnd
|| c
==TextEnd
);
705 if (AbsEnd
==sal_False
) {
706 R
.OutCh
=ConvertTextChar(c
); // von HardTrenn nach '-', ...
707 R
.Kapt
=(R
.Attrib
.Schnitt
& TextKaptBit
) !=0 && UpcasePossible(R
.OutCh
);
708 if (R
.Kapt
) R
.OutCh
=Upcase(R
.OutCh
);
709 SetTextContext(rOut
,R
.Attrib
,R
.Kapt
,0,1,1,1,1);
711 if (R
.Kapt
) c1
=Upcase(c
); else c1
=c
;
712 ChrWidth
=GetCharWidth(rOut
,c1
);
714 if (R
.Attrib
.ZAbst
!=100) { // Spezial-Zeichenabstand ?
716 Temp
=sal_uLong(ChrWidth
)*sal_uLong(R
.Attrib
.ZAbst
)/100;
717 ChrWidth
=sal_uInt16(Temp
);
720 if (R
.ChrXP
>32000) R
.ChrXP
=32000;
721 Line
[nChars
]=R
.ChrXP
-KernDist
;
723 R
.ChrXP
+=ChrWidth
-KernDist
; // Position fuer den naechsten Character
728 void FormatLine(UCHAR
* TBuf
, sal_uInt16
& Index
, ObjTextType
& Atr0
, ObjTextType
& AktAtr
,
729 sal_uInt16 UmbWdt
, sal_uInt16 AdjWdt
,
730 short* Line
, sal_uInt16
& nChars
,
732 UCHAR
* cLine
, sal_Bool TextFit
)
737 sal_Bool First
; // erster Char ?
738 sal_uInt8 Just
= 0; // Absatzformatierung
739 sal_Bool Border
; // Rand der Box erreicht ?
741 sal_Bool AbsEnd
; // Ende des Absatzes erreicht ?
742 ProcChrSta
* R
=new ProcChrSta
;
743 ProcChrSta
* R0
=new ProcChrSta
;
744 ProcChrSta
* WErec
=new ProcChrSta
;
746 ProcChrSta
* WErec0
=new ProcChrSta
;
748 ProcChrSta
* TRrec
=new ProcChrSta
;
751 sal_uInt16 WordEndCnt
; // Justieren und Trennen
755 short BoxRest
; // zum Quetschen und formatieren
759 vOut
.SetMapMode(MapMode(MAP_10TH_MM
,Point(),Fraction(1,4),Fraction(1,4)));
762 SetTextContext(vOut
,AktAtr
,sal_False
,0,1,1,1,1);
763 InitProcessCharState(*R
,AktAtr
,Index
);
764 (*R0
)=(*R
); (*WErec
)=(*R
); WEnChar
=0; c0
=0; Border0
=sal_False
;
765 Border
=sal_False
; First
=sal_True
;
768 do { // mal schauen, wieviele Worte so in die Zeile passen
769 if (Border
) c
=ProcessChar(vOut
,TBuf
,*R
,Atr0
,nChars
,DoTrenn
,Line
,cLine
);
770 else c
=ProcessChar(vOut
,TBuf
,*R
,Atr0
,nChars
,NoTrenn
,Line
,cLine
);
771 AbsEnd
=(c
==AbsatzEnd
|| c
==TextEnd
);
775 Just
=R
->Attrib
.Justify
& 0x0F; // Absatzformat steht wenn, dann am Anfang
777 Border
=R
->ChrXP
>UmbWdt
;
778 WordEnd
=(AbsEnd
|| (c
==' ')) && (c0
!=' ') && (c0
!=0);
780 if (WordEnd
&& !Border0
) {
785 if (Trenn
&& !Border
) {
794 AbsEnd
=AbsEnd
|| (nChars
>=MaxLineChars
);
795 } while (!(AbsEnd
|| (Border
&& ((WordEndCnt
>0) || WordEnd
|| Trenn
))));
797 if (Border
) { // Trennen und Quetschen
798 (*WErec0
)=(*WErec
); WEnChar0
=WEnChar
;
799 AbsEnd
=sal_False
; c0
=0;
800 (*R
)=(*WErec
); nChars
=WEnChar
;
801 (*TRrec
)=(*R
); TRnChar
=nChars
;
802 Border0
=sal_False
; Border
=sal_False
;
803 do { // erst mal gucken wieviele Silben noch reinpassen
804 ct
=ProcessChar(vOut
,TBuf
,*TRrec
,Atr0
,TRnChar
,DoTrenn
,Line
,cLine
);
805 c
=ProcessChar(vOut
,TBuf
,*R
,Atr0
,nChars
,NoTrenn
,Line
,cLine
);
806 AbsEnd
=(ct
==AbsatzEnd
) || (ct
==TextEnd
) || (nChars
>=MaxLineChars
);
808 Border
=TRrec
->ChrXP
>UmbWdt
;
809 WordEnd
=AbsEnd
|| ((AbsEnd
|| (c
==' ')) && (c0
!=' ') && (c0
!=0));
811 if (WordEnd
&& (!Border0
|| (WordEndCnt
==0))) {
814 if (AbsEnd
) WEnChar
=nChars
; else WEnChar
=nChars
-1;
815 (*TRrec
)=(*R
); TRnChar
=nChars
; // zum weitersuchen
817 if (Trenn
&& (!Border
|| (WordEndCnt
==0))) {
818 WordEndCnt
++; // merken, dass man hier trennen kann
821 (*TRrec
)=(*R
); TRnChar
=nChars
; // zum weitersuchen
825 Border
=R
->ChrXP
>UmbWdt
;
826 } while (!(AbsEnd
|| (Border
&& ((WordEndCnt
>0) || WordEnd
|| Trenn
))));
828 while (WErec0
->Index
<WErec
->Index
) { // damit Line[] auch garantiert stimmt }
829 c
=ProcessChar(vOut
,TBuf
,*WErec0
,Atr0
,WEnChar0
,WEnChar
-WEnChar0
-1,Line
,cLine
);
832 (*R
)=(*WErec
); nChars
=WEnChar
;
834 if (UmbWdt
>=R
->ChrXP
) {
835 BoxRest
=UmbWdt
-R
->ChrXP
;
836 } else { // Zusammenquetschen
837 BoxRest
=R
->ChrXP
-UmbWdt
; // um soviel muss gequetscht werden
838 for (i
=2;i
<=nChars
;i
++) { // 1. CharPosition bleibt !
839 Line
[i
]-=(i
-1)*(BoxRest
) /(nChars
-1);
842 Line
[nChars
+1]=UmbWdt
;
847 do { // Leerzeichen weglesen
849 c
=GetTextChar(TBuf
,R
->Index
,Atr0
,R
->Attrib
,NoTrenn
,sal_False
);
851 Line
[nChars
]=R
->ChrXP
;
854 if (c
!=' ' && c
!=AbsatzEnd
&& c
!=TextEnd
) {
860 if (AbsEnd
&& nChars
<MaxLineChars
) { // Ausrichten, statt Blocksatz aber linksbuendig
862 nChars
++; Line
[nChars
]=R
->ChrXP
; // Damit AbsatzEnde auch weggelesen wird
863 Line
[nChars
+1]=R
->ChrXP
; // denn die Breite von CR oder #0 ist nun mal sehr klein
864 if (TBuf
[R
->Index
-1]!=AbsatzEnd
&& TBuf
[R
->Index
-1]!=TextEnd
) {
865 c
=GetTextChar(TBuf
,R
->Index
,Atr0
,R
->Attrib
,NoTrenn
,sal_False
); // Kleine Korrektur. Notig, wenn nur 1 Wort in
869 BoxRest
=AdjWdt
-R
->ChrXP
;
870 if (TextFit
) Just
=THJustLeft
;
873 case THJustLeft
: break; // Links
875 BoxRest
=BoxRest
/2; // Mitte
876 for (i
=1;i
<=nChars
;i
++) Line
[i
]=Line
[i
]+BoxRest
;
878 case THJustRight
: { // Rechts
879 for (i
=1;i
<=nChars
;i
++) Line
[i
]=Line
[i
]+BoxRest
;
882 case THJustBlock
: { // Block und Austreibend
884 if (Just
==THJustDrvOut
) re
--;
885 while (re
>=1 && (cLine
[re
]==' ' || cLine
[re
]==TextEnd
|| cLine
[re
]==AbsatzEnd
)) re
--;
887 while (li
<=re
&& (cLine
[li
]==' ' || cLine
[li
]==TextEnd
|| cLine
[li
]==AbsatzEnd
)) li
++;
888 if (Just
==THJustDrvOut
) BoxRest
=AdjWdt
-Line
[re
+1];
890 j
=0; // Anzahl der Spaces ermitteln
891 for (i
=li
;i
<=re
;i
++) {
897 if (j
==0) { // nur 1 Wort ? -> Strecken !
898 for (i
=li
+1;i
<=re
;i
++) { // von links nach rechts
899 Line
[i
]=Line
[i
]+MulDiv(i
-li
,BoxRest
,re
-li
+1-1);
903 for (i
=li
;i
<=re
;i
++) { // j Spaces aufbohren !
904 if (cLine
[i
]==' ') { // Space gefunden !
906 h
=MulDiv(k
,BoxRest
,j
);
911 for (i
=re
+1;i
<=nChars
;i
++) Line
[i
]=Line
[i
]+BoxRest
; // und den Rest anpassen
912 Line
[nChars
+1]=AdjWdt
;
914 case THJustLocked
: { //Gesperrt
916 while (re
>=1 && (cLine
[re
]==' ' || cLine
[re
]==TextEnd
|| cLine
[re
]==AbsatzEnd
)) re
--;
918 while (li
<=re
&& (cLine
[li
]==' ' || cLine
[li
]==TextEnd
|| cLine
[li
]==AbsatzEnd
)) li
++;
919 BoxRest
=AdjWdt
-Line
[re
+1];
920 for (i
=li
+1;i
<=re
;i
++) { // Strecken von links nach rechts
921 Line
[i
]=Line
[i
]+MulDiv(i
-li
,BoxRest
,re
-li
+1-1);
923 for (i
=re
+1;i
<=nChars
;i
++) Line
[i
]=Line
[i
]+BoxRest
; // und den Rest anpassen
924 Line
[nChars
+1]=AdjWdt
;
939 /////////////////////////////////////////////////////////////////////////////////
940 /////////////////////////////////////////////////////////////////////////////////
941 /////////////////////////////////////////////////////////////////////////////////
944 /////////////////////////////////////////////////////////////////////////////////
945 /////////////////////////////////////////////////////////////////////////////////
946 /////////////////////////////////////////////////////////////////////////////////
949 void DrawChar(OutputDevice
& rOut
, UCHAR c
, ObjTextType T
, PointType Pos
, sal_uInt16 DrehWink
,
950 sal_uInt16 FitXMul
, sal_uInt16 FitXDiv
, sal_uInt16 FitYMul
, sal_uInt16 FitYDiv
)
952 SetTextContext(rOut
,T
,UpcasePossible(c
),DrehWink
,FitXMul
,FitXDiv
,FitYMul
,FitYDiv
);
953 if ((T
.Schnitt
& TextKaptBit
)!=0 && UpcasePossible(c
)) c
=Upcase(c
);
954 OUString
s(reinterpret_cast<const sal_Char
*>(&c
), 1,
955 RTL_TEXTENCODING_IBM_437
);
956 rOut
.DrawText( Point( Pos
.x
, Pos
.y
), s
);
959 /*************************************************************************
963 *************************************************************************/
964 void TextType::Draw(OutputDevice
& rOut
)
966 if ((Flags
& TextOutlBit
)!=0) return; // Sourcetext fuer Outliner !!
972 sal_uInt16 l
; // Anzahl der Zeichen in der Zeile
983 sal_uInt16 TopToBase
;
986 sal_Bool LineFit
; // FitSize.x=0? oder Flags -> jede Zeile stretchen
989 UCHAR
* cLine
; // Buffer fuer FormatLine
995 UCHAR
* Buf
=Buffer
; // Zeiger auf die Buchstaben
997 pSgfFonts
->ReadList();
998 xLine
=new short[ChrXPosArrSize
];
999 cLine
=new UCHAR
[CharLineSize
];
1001 TextFit
=(Flags
& TextFitBits
)!=0;
1003 LineFit
=((Flags
& TextFitZBit
)!=0);
1004 if (TextFit
&& FitSize
.x
==0) LineFit
=sal_True
;
1010 sn
=sin(double(DrehWink
)*3.14159265359/18000);
1011 cs
=cos(double(DrehWink
)*3.14159265359/18000);
1014 T1
=T
; Index1
=0; yPos
=0; xPos
=0;
1016 ySize
=Pos2
.y
-Pos1
.y
;
1017 xSize
=32000 /2; // Umbruch
1018 xSAdj
=Pos2
.x
-Pos1
.x
; // zum Ausrichten bei Zentriert/Blocksatz
1019 //if (xSize<=0) { xSize=32000 /2; LineFit=sal_True; }
1020 FitXMul
=sal::static_int_cast
< sal_uInt16
>(abs(Pos2
.x
-Pos1
.x
)); FitXDiv
=FitSize
.x
; if (FitXDiv
==0) FitXDiv
=1;
1021 FitYMul
=sal::static_int_cast
< sal_uInt16
>(abs(Pos2
.y
-Pos1
.y
)); FitYDiv
=FitSize
.y
; if (FitYDiv
==0) FitYDiv
=1;
1023 xSize
=Pos2
.x
-Pos1
.x
;
1025 ySize
=Pos2
.y
-Pos1
.y
;
1026 FitXMul
=1; FitXDiv
=1;
1027 FitYMul
=1; FitYDiv
=1;
1029 if (xSize
<0) xSize
=0;
1030 if (xSAdj
<0) xSAdj
=0;
1033 T2
=T1
; Index2
=Index1
;
1034 FormatLine(Buf
,Index2
,T
,T2
,xSize
,xSAdj
,xLine
,l
,sn
,cs
,cLine
,LineFit
);
1035 Fehler
=(Index2
==Index1
);
1037 lc
=GetLineFeed(Buf
,Index1
,T
,T1
,l
,LF
,MaxGrad
);
1039 if (LineFit
) FitXDiv
=xLine
[lc
+1];
1042 for (i
=1;i
<=l
+1;i
++) {
1043 Temp
=long(xLine
[i
])*long(FitXMul
) /long(FitXDiv
);
1044 xLine
[i
]=short(Temp
);
1046 LF
=MulDiv(LF
,FitYMul
,FitYDiv
);
1047 MaxGrad
=MulDiv(MaxGrad
,FitYMul
,FitYDiv
);
1049 FitXDiv
=1; // 0 gibts nicht
1053 TopToBase
=GetTopToBaseLine(MaxGrad
);
1054 yPos
=yPos
+TopToBase
;
1055 Ende
=(yPos0
+short(MulDiv(MaxGrad
,CharTopToBtm
,100))>ySize
) && !TextFit
;
1057 T2
=T1
; Index2
=Index1
;
1060 c
=GetTextCharConv(Buf
,Index2
,T
,T2
,l
-i
,sal_False
);
1061 long xp1
,yp1
; // wegen Overflowgefahr
1063 xp1
=long(Pos1
.x
)+xPos
+long(xLine
[i
]);
1064 yp1
=long(Pos1
.y
)+yPos
;
1065 if (xp1
>32000) xp1
=32000; if (xp1
<-12000) xp1
=-12000;
1066 if (yp1
>32000) yp1
=32000; if (yp1
<-12000) yp1
=-12000;
1070 if (DrehWink
!=0) RotatePoint(Pos
,Pos1
.x
,Pos1
.y
,sn
,cs
);
1071 DrawChar(rOut
,c
,T2
,Pos
,DrehWink
,FitXMul
,FitXDiv
,FitYMul
,FitYDiv
);
1075 T1
=T2
; Index1
=Index2
; // Fuer die naechste Zeile
1076 } // if ObjMin.y+yPos<=Obj_Max.y
1078 } while (c
!=TextEnd
&& !Ende
&& !Fehler
);
1083 // End of DrawText.Pas
1084 /////////////////////////////////////////////////////////////////////////////////
1085 /////////////////////////////////////////////////////////////////////////////////
1086 /////////////////////////////////////////////////////////////////////////////////
1088 // nicht mehr benoetigt, da der Pointer nun extra gefuehrt wird
1089 // (DEC Alpha hat naemlich 64Bit-Pointer!)
1090 //UCHAR* TextType::GetBufPtr()
1093 // Temp=sal_uLong(BufLo)+0x00010000*sal_uLong(BufHi);
1094 // return (UCHAR*)Temp;
1097 //void TextType::SetBufPtr(UCHAR* Ptr)
1099 // sal_uLong Temp=(sal_uLong)Ptr;
1100 // BufLo=sal_uInt16(Temp & 0x0000FFFF);
1101 // BufHi=sal_uInt16((Temp & 0xFFFF0000)>>16);
1104 sal_uInt32
ObjTextType::GetFont()
1106 return sal_uLong(FontLo
)+0x00010000*sal_uLong(FontHi
);
1109 void ObjTextType::SetFont(sal_uInt32 FontID
)
1111 FontLo
=sal_uInt16(FontID
& 0x0000FFFF);
1112 FontHi
=sal_uInt16((FontID
& 0xFFFF0000)>>16);
1116 /////////////////////////////////////////////////////////////////////////////////
1117 // SGF.Ini lesen ////////////////////////////////////////////////////////////////
1118 /////////////////////////////////////////////////////////////////////////////////
1119 SgfFontOne::SgfFontOne()
1128 SVFamil
=FAMILY_DONTKNOW
;
1129 SVChSet
=RTL_TEXTENCODING_DONTKNOW
;
1133 void SgfFontOne::ReadOne( const OString
& rID
, OString
& Dsc
)
1135 if ( Dsc
.getLength() < 4 || ( Dsc
[0] != '(' ) )
1137 sal_Int32 i
=1; // Erster Buchstabe des IF-Fontnamen. Davor ist eine '('
1138 while ( i
< Dsc
.getLength() && ( Dsc
[i
] !=')' ) )
1140 Dsc
= Dsc
.copy(i
+1); // IF-Fontname loeschen inkl. ()
1142 if ( Dsc
.getLength() < 2 || ( Dsc
[Dsc
.getLength() - 1] !=')' ) )
1144 i
=Dsc
.getLength()-2; // hier ist die ')' des SV-Fontnames
1146 while ( i
> 0 && ( Dsc
[i
] != '(' ) )
1151 SVFName
= OStringToOUString(Dsc
.copy(i
+1,j
), RTL_TEXTENCODING_IBM_437
); // SV-Fontname rausholen
1152 Dsc
= OStringBuffer(Dsc
).remove(i
,j
).makeStringAndClear();
1154 IFID
= (sal_uInt32
)rID
.toInt32();
1155 sal_Int32 nTokenCount
= comphelper::string::getTokenCount(Dsc
, ' ');
1156 for (sal_Int32 nIdx
= 0; nIdx
< nTokenCount
; ++nIdx
)
1158 OString
s(Dsc
.getToken(nIdx
, ' '));
1161 s
= s
.toAsciiUpperCase();
1162 if (s
.match("BOLD")) Bold
=sal_True
;
1163 else if (s
.match("ITAL")) Ital
=sal_True
;
1164 else if (s
.match("SERF")) Serf
=sal_True
;
1165 else if (s
.match("SANS")) Sans
=sal_True
;
1166 else if (s
.match("FIXD")) Fixd
=sal_True
;
1167 else if (s
.match("ROMAN")) SVFamil
=FAMILY_ROMAN
;
1168 else if (s
.match("SWISS")) SVFamil
=FAMILY_SWISS
;
1169 else if (s
.match("MODERN")) SVFamil
=FAMILY_MODERN
;
1170 else if (s
.match("SCRIPT")) SVFamil
=FAMILY_SCRIPT
;
1171 else if (s
.match("DECORA")) SVFamil
=FAMILY_DECORATIVE
;
1172 else if (s
.match("ANSI")) SVChSet
=RTL_TEXTENCODING_MS_1252
;
1173 else if (s
.match("IBMPC")) SVChSet
=RTL_TEXTENCODING_IBM_850
;
1174 else if (s
.match("MAC")) SVChSet
=RTL_TEXTENCODING_APPLE_ROMAN
;
1175 else if (s
.match("SYMBOL")) SVChSet
=RTL_TEXTENCODING_SYMBOL
;
1176 else if (s
.match("SYSTEM")) SVChSet
= osl_getThreadTextEncoding();
1177 else if (comphelper::string::isdigitAsciiString(s
) ) SVWidth
=sal::static_int_cast
< sal_uInt16
>(s
.toInt32());
1182 /////////////////////////////////////////////////////////////////////////////////
1184 SgfFontLst::SgfFontLst()
1193 SgfFontLst::~SgfFontLst()
1198 void SgfFontLst::RausList()
1215 void SgfFontLst::AssignFN(const String
& rFName
)
1218 void SgfFontLst::ReadList()
1227 aCfg
.SetGroup("SGV Fonts fuer StarView");
1228 sal_uInt16 Anz
=aCfg
.GetKeyCount();
1235 FID
= comphelper::string::remove(aCfg
.GetKeyName(i
), ' ');
1236 Dsc
= aCfg
.ReadKey( i
);
1237 if (comphelper::string::isdigitAsciiString(FID
))
1239 P
=new SgfFontOne
; // neuer Eintrag
1240 if (Last
!=NULL
) Last
->Next
=P
; else pList
=P
; Last
=P
; // einklinken
1241 P
->ReadOne(FID
,Dsc
); // und Zeile interpretieren
1247 SgfFontOne
* SgfFontLst::GetFontDesc(sal_uInt32 ID
)
1252 while (P
!=NULL
&& P
->IFID
!=ID
) P
=P
->Next
;
1259 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */