diff options
Diffstat (limited to 'bf_svtools/source/filter.vcl/filter/svt_sgvtext.cxx')
-rw-r--r-- | bf_svtools/source/filter.vcl/filter/svt_sgvtext.cxx | 1279 |
1 files changed, 1279 insertions, 0 deletions
diff --git a/bf_svtools/source/filter.vcl/filter/svt_sgvtext.cxx b/bf_svtools/source/filter.vcl/filter/svt_sgvtext.cxx new file mode 100644 index 000000000..82838dc4d --- /dev/null +++ b/bf_svtools/source/filter.vcl/filter/svt_sgvtext.cxx @@ -0,0 +1,1279 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <tools/config.hxx> +#include <bf_svtools/filter.hxx> +#include <comphelper/string.hxx> +#include "sgffilt.hxx" +#include "sgfbram.hxx" +#include "sgvmain.hxx" + +namespace binfilter { + +extern SgfFontLst* pSgfFonts; + +#if defined( WIN ) && defined( MSC ) +#pragma code_seg( "SVTOOLS_FILTER1", "SVTOOLS_CODE" ) +#endif + +#ifndef abs +#define abs(x) ((x)<0 ? -(x) : (x)) +#endif + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Einschraenkungen: Schatten nur grau, 2D und mit fixem Abstand. +// +// +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// AbsBase.Pas + +// die folgenden Werte sind in % vom maximalen Schriftgrad der Zeile */ +#define UndlSpace 5 /* Untersteichungsabstand von der Baseline */ +#define UndlWidth 6 /* Untersteichungsdicke */ +#define UndlSpac2 7 /* Zwischenraum bei doppelter Unterstreichung */ +#define StrkSpace 25 /* Abstand der Durchstreichlinie von der Baseline*/ +#define StrkWidth 5 /* Durchstreichungsliniendicke */ +#define StrkSpac2 7 /* Zwischenraum bei doppelter Durchstreichung */ +#define OutlWidth 2 /* Strichstaerke ist 2% vom Schriftgrad */ + +// vvv Sonderzeichen im TextBuffer vvv +#define TextEnd 0 /* ^@ Ende der Zeichenkette */ +#define HardSpace 6 /* ^F Hartspace (wird nicht umbrochen) ,' ' */ +#define GrafText 7 /* ^G Im Text eingebundene Grafik (future) */ +#define Tabulator 9 /* ^I Tabulatorzeichen, Pfeil */ +#define LineFeed 10 /* ^J Neue Zeile */ +#define SoftTrennK 11 /* ^K Zeichen fuer k-c-Austausch bei Trennung, 'k' */ +#define AbsatzEnd 13 /* ^M Neuer Absatz =CR */ +#define HardTrenn 16 /* ^P Hartes Trennzeichen (wird nicht umbrochen), '-' */ +#define SoftTrennAdd 19 /* ^S Zusatz-Zeichen Trennung von z.b."Schiff-fahrt" */ +#define Paragraf 21 /* ^U Zeichen welches fuer Paragraf-Zeichen */ +#define Escape 27 /* ^[ Escapesequenz einleiten */ +#define SoftTrenn 31 /* ^_ Weiches Trennzeichen, '-' nur Zeilenende */ +#define MaxEscValLen 8 +#define MaxEscLen (MaxEscValLen+3) + +//============================================================================== +// Escapesequenzen: [Esc]<Ident><Value>[Esc] also mind. 4 Char +// Max. Laenge von Value soll sein: 8 Char (7+Vorzeichen). Demnach max. Laenge +// einer Escapesequenz: 11 Char. +// Identifer: + +#define EscFont 'F' /* FontID, z.B. 92500 fuer CG Times */ +#define EscGrad 'G' /* Schriftgrad 1..255 fuer <<Pt-127<<Pt */ +#define EscBreit 'B' /* Breite 1..255% des Schriftgrades */ +#define EscKaptS 'K' /* Kapitaelchengroesse 1..255% des Schriftgrades */ +#define EscLFeed 'L' /* Zeilenabstand 1..32767% vom max. Schriftgrad der Zeile */ + // oder 1..32767 fuer 1..16383<<Pt absolut (Wenn Bit 15=1) +#define EscSlant 'S' /* Kursiv(Winkel) 1..8999 fuer 0.01deg..89.99deg */ +#define EscVPos 'V' /* Zeichen Vertikal-Position 1..255 fuer <<Pt..127<<Pt */ +#define EscZAbst 'Z' /* Zeichenabstand -128..127% */ +#define EscHJust 'A' /* H-Justify Absatz: Links, Zentr, Rechts, Block, Austreibend, Gesperrt (0..5)*/ + +#define EscFarbe 'C' /* Farbe 0..7 */ +#define EscBFarb 'U' /* BackFarbe 0..7 */ +#define EscInts 'I' /* Farbintensitaet 0..100% */ +#define EscMustr 'M' /* Muster 0..? inkl. Transp... */ +#define EscMFarb 'O' /* Musterfarbe 0..7 */ +#define EscMBFrb 'P' /* 2. Musterfarbe 0..7 */ +#define EscMInts 'W' /* Musterintensitaet 0..7 */ + +#define EscSMstr 'E' /* Schattenmuster 0..? inkl. Transp... */ +#define EscSFarb 'R' /* Schattenfarbe 0..7 */ +#define EscSBFrb 'T' /* 2. Schattenfarbe 0..7 */ +#define EscSInts 'Q' /* Schattenintensitaet 0..7 */ + +#define EscSXDst 'X' /* Schattenversatz X 0..100% */ +#define EscSYDst 'Y' /* Schattenversatz Y 0..100% */ +#define EscSDist 'D' /* Schattenversatz X-Y 0..100% */ + +#define EscBold 'f' /* Fett */ +#define EscLSlnt 'l' /* LKursiv */ +#define EscRSlnt 'r' /* RKursiv */ +#define EscUndln 'u' /* Unterstrichen */ +#define EscDbUnd 'p' /* doppelt Unterstrichen */ +#define EscKaptF 'k' /* Kapitaelchenflag */ +#define EscStrik 'd' /* Durchgestrichen */ +#define EscDbStk 'e' /* doppelt Durchgestrichen */ +#define EscSupSc 'h' /* Hochgestellt */ +#define EscSubSc 't' /* Tiefgestellt */ +#define Esc2DShd 's' /* 2D-Schatten */ +#define Esc3DShd 'j' /* 3D-Schatten */ +#define Esc4DShd 'i' /* 4D-Schatten */ +#define EscEbShd 'b' /* Embossed */ + +// AllEscIdent =[EscFont, EscGrad, EscBreit,EscKaptS,EscLFeed,EscSlant,EscVPos, EscZAbst,EscHJust, +// EscFarbe,EscBFarb,EscInts, EscMustr,EscMFarb,EscMBFrb,EscMInts, +// EscSMstr,EscSFarb,EscSBFrb,EscSInts,EscSXDst,EscSYDst,EscSDist, +// EscBold, EscLSlnt,EscRSlnt,EscUndln,EscDbUnd,EscKaptF,EscStrik,EscDbStk, +// EscSupSc,EscSubSc,Esc2DShd,Esc3DShd,Esc4DShd]; +// Justify muss spaetestens am Anfang des Absatzes stehen +#define EscSet '' /* Flag setzen */ +#define EscReset '' /* Flag loeschen */ +#define EscDeflt '\x11' /* Flag auf default setzen */ +#define EscToggl '' /* Flag Toggeln */ +#define EscRelat '%' +#define EscNoFlg 0 +#define EscNoVal -2147483647 /* -MaxLongInt */ +//============================================================================== +#define NoTrenn 0xFFFF /* Wert fuer Parameter 'Rest' von GetTextChar(), wenn auf keinen Fall getrennt werden soll */ +#define DoTrenn 0xFFFE /* Wert fuer Parameter 'Rest' von GetTextChar(), wenn getrennt werden soll */ + +#define MaxLineChars 1024 + +#define ChrXPosArrSize (MaxLineChars+1+1) /* 2k - Beginnt mit 0 im gegensatz zu StarDraw */ +#define CharLineSize (MaxLineChars+1+1) +#define EscStr (UCHAR[MaxEscLen+1]); + +#define MinChar 32 +#define MaxChar 255 + + +//============================================================================== + +#define DefaultCharWidth 4800 +#define GradDiv 2 +#define CharTopToBase 100 /* wegen Apostrophe und Umlaute mehr als 75% */ +#define CharTopToBtm 120 /* Zeilenhoehe ist groesser als Schriftgrad */ + // bei Avanti-Bold 'ue' eigentlich sogar 130% + +// end of AbsBase.Pas +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + + + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// DefBase.Pas + +#define TextBoldBit 0x0001 /* Fett */ +#define TextRSlnBit 0x0002 /* Kursiv */ +#define TextUndlBit 0x0004 /* Unterstrichen */ +#define TextStrkBit 0x0008 /* Durchgesteichen */ +#define TextSupSBit 0x0010 /* Hocgestellt */ +#define TextSubSBit 0x0020 /* Tiefgestellt */ +#define TextKaptBit 0x0040 /* Kapitaelchen */ +#define TextLSlnBit 0x0080 /* Linkskursiv */ +#define TextDbUnBit 0x0100 /* Doppelt unterstrichen */ +#define TextDbStBit 0x0200 /* Doppelt durchgestrichen */ +#define TextSh2DBit 0x0400 /* 2D-Schatten 2.0 */ +#define TextSh3DBit 0x0800 /* 3D-Schatten 2.0 */ +#define TextSh4DBit 0x1000 /* 4D-Schatten 2.0 */ +#define TextShEbBit 0x2000 /* Embossed-Schatten 2.0 */ +#define FontAtrBits (TextBoldBit | TextRSlnBit) + +#define THJustLeft 0x00 +#define THJustCenter 0x01 +#define THJustRight 0x02 +#define THJustBlock 0x03 +#define THJustDrvOut 0x04 /* Austreibend Formatiert */ +#define THJustLocked 0x05 /* A l s S p e r r s c h r i f t */ +#define TVJustTop 0x00 /* Future */ +#define TVJustCenter 0x10 /* Future */ +#define TVJustBottom 0x20 /* Future */ +#define TVJustBlock 0x30 /* Future */ + +#define MaxCharSlant 4200 /* Maximal 42deg kursiv ! */ + +// end of DefBase.Pas +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + +BOOL CheckTextOutl(ObjAreaType& F, ObjLineType& L); + +BOOL CheckTextOutl(ObjAreaType& F, ObjLineType& L) +{ + return (F.FIntens!=L.LIntens) || + ((F.FFarbe!=L.LFarbe) && (F.FIntens>0)) || + ((F.FBFarbe!=L.LBFarbe) && (F.FIntens<100)); +} + + +short hPoint2Sgf(short a) +{ + long b; + b=long(a)*127*SgfDpmm/(144*5); + return short(b); +} + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// AbsRead.Pas + +// ====================================================================== +// Function GetTopToBaseLine() Function GetBaseLineToBtm() +// +// Abstand von Zeilenoberkante bis BaseLine bzw. von BaseLine bis +// Unterkante berechnen. Alles in SGF-Units. +// ====================================================================== + +USHORT GetTopToBaseLine(USHORT MaxGrad) +{ + long ret; + ret=long(MaxGrad)*long(CharTopToBase) /long(100); + return USHORT(ret); +} + +// ====================================================================== +// Function GetTextChar() Function GetTextCharConv() +// +// Liest ein Zeichen aus dem Textbuffer, wertet dabei eventuell +// auftretende Escapesequenzen aus und setzt dementsprechend den +// Ein-/Ausgabeparameter AktAtr. Index wird entsprechend erhoeht. +// Der Parameter Rest muss immer die Anzahl der Zeichen beinhalten, +// den angeforderten Zeichen in der aktuellen Zeile noch folgen. +// Ansonsten funktioniert die Silbentrennung nicht richtig. Gibt man +// stattdessen die Konstante NoTrenn an, wird in keinem Fall +// getrennt, die Konstante DoTrenn bewirkt dagegen, dass ueberall dort +// getrennt wird, wo ein SoftTrenner vorkommt. +// +// SoftTrenner werden immer in ein Minuszeichen konvertiert. +// GetTextCharConv() konvertiert zusaetzlich HardSpace und AbsatzEnde +// in Spaces sowie HardTrenner in Minuszeichen. TextEnde wird immer +// als Char(0) geliefert. +// ====================================================================== + + + +UCHAR ConvertTextChar(UCHAR c) +{ + if (c<32) { + switch (c) { + case HardSpace : c=' '; break; + case AbsatzEnd : c=' '; break; + case SoftTrenn : c='-'; break; + case HardTrenn : c='-'; break; + case SoftTrennK : c='-'; break; + case SoftTrennAdd: c='-'; + } + } + return c; +} + +long ChgValue(long Def, long Min, long Max, UCHAR FlgVal, long NumVal) +{ + long r=0; + + if (FlgVal==EscDeflt) { + r=Def; // zurueck auf Default + } else { + if (NumVal!=EscNoVal) r=NumVal; // Hart setzen + } + + if (Min!=0 || Max!=0) { + if (r>Max) r=Max; + if (r<Min) r=Min; + } + return r; +} + + + +void ChgSchnittBit(USHORT Bit, USHORT Radio1, USHORT Radio2, USHORT Radio3, + UCHAR FlgVal, USHORT Schnitt0, USHORT& Schnitt) +{ + USHORT All,Rad; + + Rad=Radio1 | Radio2 | Radio3; + All=Bit | Rad; + + switch (FlgVal) { + case EscSet : Schnitt=(Schnitt & ~All) | Bit; break; + case EscReset: Schnitt=(Schnitt & ~All); break; + case EscDeflt: Schnitt=(Schnitt & ~All) | (Schnitt0 & All); break; + case EscToggl: Schnitt=(Schnitt & ~Rad) ^ Bit; + } +} + + + +UCHAR GetNextChar(UCHAR* TBuf, USHORT Index) +{ + USHORT Cnt; + while (TBuf[Index]==Escape) { + Index++; + Cnt=0; + while (TBuf[Index]!=Escape && Cnt<=MaxEscLen) { + Index++; Cnt++; } + Index++; + } + return TBuf[Index]; +} + + + +UCHAR ProcessOne(UCHAR* TBuf, USHORT& Index, + ObjTextType& Atr0, ObjTextType& AktAtr, + BOOL ScanEsc) +{ + UCHAR c; + UCHAR Ident; + BOOL Ende; + BOOL q; + UCHAR FlgVal; + long NumVal; + long Sgn; + short i; + BOOL EoVal; + + do { + c=TBuf[Index]; Index++; + Ende=(c!=Escape); + if (Ende==FALSE) { + c=TBuf[Index]; Index++; + Ident=c; // Identifer merken + FlgVal=EscNoFlg; + NumVal=EscNoVal; + c=TBuf[Index]; Index++; // Hier faengt der Wert an + if (c==EscSet || c==EscReset || c==EscDeflt || c==EscToggl) FlgVal=c; else { + if (c=='-') Sgn=-1; else Sgn=1; + if (c=='+' || c=='-') { c=TBuf[Index]; Index++; } + i=MaxEscValLen; + NumVal=0; + do { + NumVal=10*NumVal+c-'0'; + EoVal=(TBuf[Index]<'0' || TBuf[Index]>'9'); + if (EoVal==FALSE) { c=TBuf[Index]; Index++; } + i--; + } while (i>0 && EoVal==FALSE); + NumVal=Sgn*NumVal; + } + q=!CheckTextOutl(AktAtr.F,AktAtr.L); + + switch (Ident) { + case EscFont : AktAtr.SetFont(ULONG (ChgValue(Atr0.GetFont(),0,0 ,FlgVal,NumVal)));break; + case EscGrad : AktAtr.Grad =USHORT(ChgValue(Atr0.Grad, 2,2000 ,FlgVal,NumVal)); break; + case EscBreit: AktAtr.Breite =USHORT(ChgValue(Atr0.Breite, 1,1000 ,FlgVal,NumVal)); break; + case EscKaptS: AktAtr.Kapit =(BYTE)(ChgValue(Atr0.Kapit, 1,255 ,FlgVal,NumVal)); break; + case EscLFeed: AktAtr.LnFeed =USHORT(ChgValue(Atr0.LnFeed, 1,65535 ,FlgVal,NumVal)); break; + case EscSlant: AktAtr.Slant =USHORT(ChgValue(Atr0.Slant, 1,MaxCharSlant ,FlgVal,NumVal)); break; + case EscVPos : AktAtr.ChrVPos=char (ChgValue(Atr0.ChrVPos,-128,127 ,FlgVal,NumVal)); break; + case EscZAbst: AktAtr.ZAbst =(BYTE)(ChgValue(Atr0.ZAbst, 1,255 ,FlgVal,NumVal)); break; + case EscHJust: AktAtr.Justify=(BYTE)(ChgValue(Atr0.Justify & 0x0F,0,5 ,FlgVal,NumVal)); break; + case EscFarbe: { AktAtr.L.LFarbe =(BYTE)(ChgValue(Atr0.L.LFarbe,0,7 ,FlgVal,NumVal)); if (q) AktAtr.F.FFarbe =AktAtr.L.LFarbe; } break; + case EscBFarb: { AktAtr.L.LBFarbe=(BYTE)(ChgValue(Atr0.L.LBFarbe,0,255,FlgVal,NumVal)); if (q) AktAtr.F.FBFarbe=AktAtr.L.LBFarbe; } break; + case EscInts : { AktAtr.L.LIntens=(BYTE)(ChgValue(Atr0.L.LIntens,0,100,FlgVal,NumVal)); if (q) AktAtr.F.FIntens=AktAtr.L.LIntens; } break; + + case EscMustr: { AktAtr.F.FMuster=USHORT(ChgValue(Atr0.F.FMuster,0,65535,FlgVal,NumVal)); } break; + case EscMFarb: { AktAtr.F.FFarbe =(BYTE)(ChgValue(Atr0.F.FFarbe,0,7 ,FlgVal,NumVal)); } break; + case EscMBFrb: { AktAtr.F.FBFarbe=(BYTE)(ChgValue(Atr0.F.FBFarbe,0,255,FlgVal,NumVal)); } break; + case EscMInts: { AktAtr.F.FIntens=(BYTE)(ChgValue(Atr0.F.FIntens,0,100,FlgVal,NumVal)); } break; + + case EscSMstr: { AktAtr.ShdF.FMuster=USHORT(ChgValue(Atr0.ShdF.FMuster,0,65535,FlgVal,NumVal)); } break; + case EscSFarb: { AktAtr.ShdL.LFarbe =(BYTE)(ChgValue(Atr0.ShdL.LFarbe,0,7 ,FlgVal,NumVal)); AktAtr.ShdF.FFarbe =AktAtr.ShdL.LFarbe; } break; + case EscSBFrb: { AktAtr.ShdL.LBFarbe=(BYTE)(ChgValue(Atr0.ShdL.LBFarbe,0,255,FlgVal,NumVal)); AktAtr.ShdF.FBFarbe=AktAtr.ShdL.LBFarbe; } break; + case EscSInts: { AktAtr.ShdL.LIntens=(BYTE)(ChgValue(Atr0.ShdL.LIntens,0,100,FlgVal,NumVal)); AktAtr.ShdF.FIntens=AktAtr.ShdL.LIntens; } break; + case EscSDist: { AktAtr.ShdVers.x=(short)ChgValue(Atr0.ShdVers.x,0,30000,FlgVal,NumVal); AktAtr.ShdVers.y=AktAtr.ShdVers.x; } break; + case EscSXDst: { AktAtr.ShdVers.x=(short)ChgValue(Atr0.ShdVers.x,0,30000,FlgVal,NumVal); } break; + case EscSYDst: { AktAtr.ShdVers.y=(short)ChgValue(Atr0.ShdVers.y,0,30000,FlgVal,NumVal); } break; + + case EscBold : ChgSchnittBit(TextBoldBit,0,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscRSlnt: ChgSchnittBit(TextRSlnBit,TextLSlnBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscUndln: ChgSchnittBit(TextUndlBit,TextDbUnBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscStrik: ChgSchnittBit(TextStrkBit,TextDbStBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscDbUnd: ChgSchnittBit(TextDbUnBit,TextUndlBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscDbStk: ChgSchnittBit(TextDbStBit,TextStrkBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscSupSc: ChgSchnittBit(TextSupSBit,TextSubSBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscSubSc: ChgSchnittBit(TextSubSBit,TextSupSBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscKaptF: ChgSchnittBit(TextKaptBit,0,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscLSlnt: ChgSchnittBit(TextLSlnBit,TextRSlnBit,0,0 ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case Esc2DShd: ChgSchnittBit(TextSh2DBit,TextSh3DBit,TextSh4DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case Esc3DShd: ChgSchnittBit(TextSh3DBit,TextSh2DBit,TextSh4DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case Esc4DShd: ChgSchnittBit(TextSh4DBit,TextSh2DBit,TextSh3DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + case EscEbShd: ChgSchnittBit(TextShEbBit,TextSh2DBit,TextSh3DBit,TextSh4DBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break; + } //endcase + if (TBuf[Index]==Escape) Index++; // zweites Esc weglesen } + } // if Ende==FALSE + } while (Ende==FALSE && ScanEsc==FALSE); + if (Ende==FALSE) c=Escape; + return c; +} // end of ProcessOne + + +UCHAR GetTextChar(UCHAR* TBuf, USHORT& Index, + ObjTextType& Atr0, ObjTextType& AktAtr, + USHORT Rest, BOOL ScanEsc) +{ + UCHAR c,c0,nc; + + c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); + if (ScanEsc==FALSE) { + if (c==SoftTrennAdd || c==SoftTrennK || c==SoftTrenn) { + nc=GetNextChar(TBuf,Index); + c0=c; + if (Rest==0 || Rest==DoTrenn || + nc==' ' || nc==AbsatzEnd || nc==TextEnd) c='-'; + else { + c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); // den Trenner ueberspringen + if (c0==SoftTrennAdd) { + if (c>=32) c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); // und hier noch 'nen Buchstaben ueberspringen + } + } + } + if ((Rest==1 || Rest==DoTrenn) && GetNextChar(TBuf,Index)==SoftTrennK) { + if (c=='c') c='k'; + else if (c=='C') c='K'; + } + } + return c; +} + + // HardSpace und HardTrenn muessen explizit konvertiert werden ! } + // if AktAtr.Schnitt and TextKaptBit =TextKaptBit then c:=UpCase(c);(explizit) } + + // Bei der Trennmethode SoftTrennAdd wird davon ausgegangen, dass der zu } + // trennende Konsonant bereits 3x mal im TextBuf vorhanden ist, z.b.: } + // "Schiff-fahrt". Wenn nicht getrennt, dann wird "-f" entfernt. } + + + +UCHAR GetTextCharConv(UCHAR* TBuf, USHORT& Index, + ObjTextType& Atr0, ObjTextType& AktAtr, + USHORT Rest, BOOL ScanEsc) +{ + UCHAR c; + + c=GetTextChar(TBuf,Index,Atr0,AktAtr,Rest,ScanEsc); + if (c<32) { + switch (c) { + case HardSpace : c=' '; break; + case AbsatzEnd : c=' '; break; + case HardTrenn : c='-'; + } + } + return c; +} + + +// ====================================================================== +// Function GetLineFeed() +// +// Benoetigter Zeilenabstand in SGF-Units. ChrVPos wird beruecksichtigt. +// ====================================================================== +USHORT GetLineFeed(UCHAR* TBuf, USHORT Index, ObjTextType Atr0, ObjTextType AktAtr, + USHORT nChar, USHORT& LF, USHORT& MaxGrad) +{ + UCHAR c=0; + BOOL AbsEnd=FALSE; + ULONG LF100=0; + ULONG MaxLF100=0; + BOOL LFauto=0; + BOOL First=TRUE; + USHORT Grad; + USHORT i=0; + USHORT r=1; + + MaxGrad=0; + while (!AbsEnd && nChar>0) { + nChar--; + c=GetTextChar(TBuf,Index,Atr0,AktAtr,nChar,FALSE); + i++; + AbsEnd=(c==TextEnd || c==AbsatzEnd); + if (First || (!AbsEnd && c!=' ' && c!=HardTrenn)) { + LFauto=(AktAtr.LnFeed & 0x8000)==0; + LF100=AktAtr.LnFeed & 0x7FFF; + if (LFauto) LF100=LF100*AktAtr.Grad; else LF100*=LF100; + if (AktAtr.ChrVPos>0) LF100-=AktAtr.ChrVPos*100; + if (LF100>MaxLF100) MaxLF100=LF100; + Grad=AktAtr.Grad; + if (AktAtr.ChrVPos>0) Grad=Grad-AktAtr.ChrVPos; + if (Grad>MaxGrad) MaxGrad=Grad; + First=FALSE; + } + if (!AbsEnd && c!=' ') r=i; + } + MaxGrad=hPoint2Sgf(MaxGrad); + if (MaxLF100<=4000) { // sonst Overflowgefahr + LF=USHORT(hPoint2Sgf(short(MaxLF100)) /100); + } else { + LF=USHORT(hPoint2Sgf(short(MaxLF100) /100)); + } + + return r; +} + +// End of AbsRead.Pas +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + + + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// iFont.Pas + +#define DefaultSlant 1500 /* Default: Italic ist 15deg */ +#define SuperSubFact 60 /* SuperScript/SubScript: 60% vom Schriftgrad */ +#define DefaultSpace 40 /* Default: Space ist 40% vom SchriftGrad */ + +USHORT SetTextContext(OutputDevice& rOut, ObjTextType& Atr, BOOL Kapt, USHORT Dreh, + USHORT FitXMul, USHORT FitXDiv, USHORT FitYMul, USHORT FitYDiv) +{ + SgfFontOne* pSgfFont; // Font aus dem IniFile + Font aFont; + Color aColor; + ULONG Grad; + ULONG Brei; + String FNam; + USHORT StdBrei=50; // Durchschnittliche Zeichenbreite in % von Schriftgrad + BOOL bFit=(FitXMul!=1 || FitXDiv!=1 || FitYMul!=1 || FitYDiv!=1); + + pSgfFont = pSgfFonts->GetFontDesc(Atr.GetFont()); + + if ( pSgfFont!=NULL ) + { + FNam =pSgfFont->SVFName; + StdBrei=pSgfFont->SVWidth; + if (pSgfFont->Fixd) aFont.SetPitch(PITCH_FIXED); else aFont.SetPitch(PITCH_VARIABLE); + aFont.SetFamily(pSgfFont->SVFamil); + aFont.SetCharSet(pSgfFont->SVChSet); + aFont.SetName(FNam); + } + else + { // Falls nich im Inifile, sind hier einige Fonts hart kodiert + aFont.SetPitch(PITCH_VARIABLE); + switch (Atr.GetFont()) { + case 92500: case 92501: case 92504: case 92505: + { +#if defined(WIN) || defined(WNT) || defined(PM2) + FNam=String::CreateFromAscii( "Times New Roman" ); // CG Times ist unter Windows und OS/2 Times New Roman +#else + FNam=String::CreateFromAscii( "Times" ); // ansonsten ist das einfach Times +#endif + StdBrei=40; + aFont.SetFamily(FAMILY_ROMAN); + } break; + case 94021: case 94022: case 94023: case 94024: { +#if defined(WIN) || defined(WNT) + FNam=String::CreateFromAscii( "Arial", 5 ); // Univers ist unter Windows Arial +#else + FNam=String::CreateFromAscii( "Helvetica" ); // und ansonsten Helvetica +#endif + aFont.SetFamily(FAMILY_SWISS); + StdBrei=47; + } break; + case 93950: case 93951: case 93952: case 93953: { +#if defined(WIN) || defined(WNT) + FNam=String::CreateFromAscii( "Courier New" ); // Der Vector-Courierfont unter Windows heisst Courier New +#else + FNam=String::CreateFromAscii( "Courier" ); // ansonsten ist und bleibt Courier immer Courier +#endif + aFont.SetFamily(FAMILY_ROMAN); + aFont.SetPitch(PITCH_FIXED); + } break; + default: FNam=String::CreateFromAscii( "Helvetica", 9 ); + } + aFont.SetName(FNam); + //aFont.SetCharSet(CHARSET_SYSTEM); + } + + Grad=ULONG(Atr.Grad); + if ((Atr.Schnitt & TextKaptBit) !=0 && Kapt) Grad=Grad*ULONG(Atr.Kapit)/100; + if ((Atr.Schnitt & TextSupSBit) !=0 || (Atr.Schnitt & TextSubSBit) !=0) Grad=Grad*SuperSubFact/100; + Brei=Grad; + if (Atr.Breite!=100 || bFit) { + if (bFit) { + Grad=Grad*ULONG(FitYMul)/ULONG(FitYDiv); + Brei=Brei*ULONG(FitXMul)/ULONG(FitXDiv); + } + Brei=Brei*ULONG(Atr.Breite)/100; + Brei=Brei*ULONG(StdBrei)/100; + aFont.SetSize(Size(hPoint2Sgf(USHORT(Brei)),hPoint2Sgf(USHORT(Grad)))); + } else { + aFont.SetSize(Size(0,hPoint2Sgf(USHORT(Grad)))); + } + + aColor=Sgv2SvFarbe(Atr.L.LFarbe,Atr.L.LBFarbe,Atr.L.LIntens); aFont.SetColor(aColor); + aColor=Sgv2SvFarbe(Atr.F.FFarbe,Atr.F.FBFarbe,Atr.F.FIntens); aFont.SetFillColor(aColor); + aFont.SetTransparent(TRUE); + aFont.SetAlign(ALIGN_BASELINE); + + Dreh/=10; Dreh=3600-Dreh; if (Dreh==3600) Dreh=0; + aFont.SetOrientation(Dreh); + + if ((Atr.Schnitt & TextBoldBit) !=0) aFont.SetWeight(WEIGHT_BOLD); + if ((Atr.Schnitt & TextRSlnBit) !=0) aFont.SetItalic(ITALIC_NORMAL); + if ((Atr.Schnitt & TextUndlBit) !=0) aFont.SetUnderline(UNDERLINE_SINGLE); + if ((Atr.Schnitt & TextDbUnBit) !=0) aFont.SetUnderline(UNDERLINE_DOUBLE); + if ((Atr.Schnitt & TextStrkBit) !=0) aFont.SetStrikeout(STRIKEOUT_SINGLE); + if ((Atr.Schnitt & TextDbStBit) !=0) aFont.SetStrikeout(STRIKEOUT_DOUBLE); + if ((Atr.Schnitt & TextSh2DBit) !=0) aFont.SetShadow(TRUE); + if ((Atr.Schnitt & TextSh3DBit) !=0) aFont.SetShadow(TRUE); + if ((Atr.Schnitt & TextSh4DBit) !=0) aFont.SetShadow(TRUE); + if ((Atr.Schnitt & TextShEbBit) !=0) aFont.SetShadow(TRUE); + if (CheckTextOutl(Atr.F,Atr.L)) aFont.SetOutline(TRUE); + + if (aFont!=rOut.GetFont()) rOut.SetFont(aFont); + + return 0; +} + +// iFont.Pas +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// Absatz.Pas + +struct ProcChrSta { + USHORT Index; + USHORT ChrXP; + UCHAR OutCh; + BOOL Kapt; + ObjTextType Attrib; +}; + +void InitProcessCharState(ProcChrSta& State, ObjTextType& AktAtr, USHORT IndexA) +{ + State.Attrib=AktAtr; + State.OutCh=0; + State.Index=IndexA; + State.ChrXP=0; + State.Kapt=FALSE; +} + +BOOL UpcasePossible(UCHAR c) +{ + if ((c>='a' && c<='z') || c == 0xe4 || c == 0xf6 || c == 0xfc ) return TRUE; + else return FALSE; +} + +UCHAR Upcase(UCHAR c) +{ + if ((c>=(UCHAR)'a' && c<=(UCHAR)'z')) c=(c-(UCHAR)'a')+(UCHAR)'A'; + else if ( c == 0xe4 ) c = 0xc4; + else if ( c == 0xf6 ) c = 0xd6; + else if ( c == 0xfc ) c = 0xdc; + return c; +} + +USHORT GetCharWidth(OutputDevice& rOut, UCHAR c) +{ + USHORT ChrWidth; + + if (c==' ') + { + ChrWidth=(USHORT)rOut.GetTextWidth( String('A') ); + if (rOut.GetFont().GetPitch()!=PITCH_FIXED) { + ChrWidth=MulDiv(ChrWidth,DefaultSpace,100); + } + } else { + // with MaxChar == 255 c cannot be greater than MaxChar + // assert if MaxChar is ever changed + OSL_ENSURE( MaxChar == 255, "MaxChar not 255" ); + if (c>=MinChar /*&& c<=MaxChar*/) + { + ChrWidth=(USHORT)rOut.GetTextWidth(rtl::OUString(reinterpret_cast<sal_Char*>(&c), 1, RTL_TEXTENCODING_IBM_437)); + } + else + { + ChrWidth=(USHORT)rOut.GetTextWidth(rtl::OUString(static_cast<sal_Unicode>('A'))); + } + } + return ChrWidth; +} + +UCHAR ProcessChar(OutputDevice& rOut, UCHAR* TBuf, ProcChrSta& R, ObjTextType& Atr0, + USHORT& nChars, USHORT Rest, + short* Line, UCHAR* cLine) +{ + USHORT KernDist=0; // Wert fuer Kerning + USHORT ChrWidth; + UCHAR c; + UCHAR c1; + BOOL AbsEnd; + + c=GetTextChar(TBuf,R.Index,Atr0,R.Attrib,Rest,FALSE); // versucht evtl. zu trennen, wenn Rest entsprechenden Wert besitzt + + AbsEnd=(c==AbsatzEnd || c==TextEnd); + if (AbsEnd==FALSE) { + R.OutCh=ConvertTextChar(c); // von HardTrenn nach '-', ... + R.Kapt=(R.Attrib.Schnitt & TextKaptBit) !=0 && UpcasePossible(R.OutCh); + if (R.Kapt) R.OutCh=Upcase(R.OutCh); + SetTextContext(rOut,R.Attrib,R.Kapt,0,1,1,1,1); + + if (R.Kapt) c1=Upcase(c); else c1=c; + ChrWidth=GetCharWidth(rOut,c1); + + if (R.Attrib.ZAbst!=100) { // Spezial-Zeichenabstand ? + ULONG Temp; + Temp=ULONG(ChrWidth)*ULONG(R.Attrib.ZAbst)/100; + ChrWidth=USHORT(Temp); + } + nChars++; + if (R.ChrXP>32000) R.ChrXP=32000; + Line[nChars]=R.ChrXP-KernDist; + cLine[nChars]=c; + R.ChrXP+=ChrWidth-KernDist; // Position fuer den naechsten Character + } + return c; +} + +void FormatLine(UCHAR* TBuf, USHORT& Index, ObjTextType& Atr0, ObjTextType& AktAtr, + USHORT UmbWdt, USHORT AdjWdt, + short* Line, USHORT& nChars, + double, double, + UCHAR* cLine, BOOL TextFit) +{ + VirtualDevice vOut; + UCHAR c,c0; + UCHAR ct; + BOOL First; // erster Char ? + BYTE Just = 0; // Absatzformatierung + BOOL Border; // Rand der Box erreicht ? + BOOL Border0; + BOOL AbsEnd; // Ende des Absatzes erreicht ? + ProcChrSta* R=new ProcChrSta; + ProcChrSta* R0=new ProcChrSta; + ProcChrSta* WErec=new ProcChrSta; + USHORT WEnChar; + ProcChrSta* WErec0=new ProcChrSta; + USHORT WEnChar0; + ProcChrSta* TRrec=new ProcChrSta; + USHORT TRnChar; + + USHORT WordEndCnt; // Justieren und Trennen + BOOL WordEnd; + BOOL Trenn; + + short BoxRest; // zum Quetschen und formatieren + USHORT i,j,k,h; + USHORT re,li; + + vOut.SetMapMode(MapMode(MAP_10TH_MM,Point(),Fraction(1,4),Fraction(1,4))); + + nChars=0; + SetTextContext(vOut,AktAtr,FALSE,0,1,1,1,1); + InitProcessCharState(*R,AktAtr,Index); + (*R0)=(*R); (*WErec)=(*R); WEnChar=0; c0=0; Border0=FALSE; + Border=FALSE; First=TRUE; + WordEndCnt=0; + + do { // mal schauen, wieviele Worte so in die Zeile passen + if (Border) c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,DoTrenn,Line,cLine); + else c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,NoTrenn,Line,cLine); + AbsEnd=(c==AbsatzEnd || c==TextEnd); + //if not AbsEnd then + { + if (First) { + Just=R->Attrib.Justify & 0x0F; // Absatzformat steht wenn, dann am Anfang + } + Border=R->ChrXP>UmbWdt; + WordEnd=(AbsEnd || (c==' ')) && (c0!=' ') && (c0!=0); + Trenn=c=='-'; + if (WordEnd && !Border0) { + WordEndCnt++; + (*WErec)=(*R0); + WEnChar=nChars-1; + } + if (Trenn && !Border) { + WordEndCnt++; + (*WErec)=(*R); + WEnChar=nChars; + } + } + (*R0)=(*R); c0=c; + Border0=Border; + First=FALSE; + AbsEnd=AbsEnd || (nChars>=MaxLineChars); + } while (!(AbsEnd || (Border && ((WordEndCnt>0) || WordEnd || Trenn)))); + + if (Border) { // Trennen und Quetschen + (*WErec0)=(*WErec); WEnChar0=WEnChar; + AbsEnd=FALSE; c0=0; + (*R)=(*WErec); nChars=WEnChar; + (*TRrec)=(*R); TRnChar=nChars; + Border0=FALSE; Border=FALSE; + do { // erst mal gucken wieviele Silben noch reinpassen + ct=ProcessChar(vOut,TBuf,*TRrec,Atr0,TRnChar,DoTrenn,Line,cLine); + c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,NoTrenn,Line,cLine); + AbsEnd=(ct==AbsatzEnd) || (ct==TextEnd) || (nChars>=MaxLineChars); + + Border=TRrec->ChrXP>UmbWdt; + WordEnd=AbsEnd || ((AbsEnd || (c==' ')) && (c0!=' ') && (c0!=0)); + Trenn=ct=='-'; + if (WordEnd && (!Border0 || (WordEndCnt==0))) { + WordEndCnt++; + (*WErec)=(*R0); + if (AbsEnd) WEnChar=nChars; else WEnChar=nChars-1; + (*TRrec)=(*R); TRnChar=nChars; // zum weitersuchen + } + if (Trenn && (!Border || (WordEndCnt==0))) { + WordEndCnt++; // merken, dass man hier trennen kann + (*WErec)=(*TRrec); + WEnChar=TRnChar; + (*TRrec)=(*R); TRnChar=nChars; // zum weitersuchen + } + (*R0)=(*R); c0=c; + Border0=Border; + Border=R->ChrXP>UmbWdt; + } while (!(AbsEnd || (Border && ((WordEndCnt>0) || WordEnd || Trenn)))); + + while (WErec0->Index<WErec->Index) { // damit Line[] auch garantiert stimmt } + c=ProcessChar(vOut,TBuf,*WErec0,Atr0,WEnChar0,WEnChar-WEnChar0-1,Line,cLine); + } + + (*R)=(*WErec); nChars=WEnChar; + + if (UmbWdt>=R->ChrXP) { + BoxRest=UmbWdt-R->ChrXP; + } else { // Zusammenquetschen + BoxRest=R->ChrXP-UmbWdt; // um soviel muss gequetscht werden + for (i=2;i<=nChars;i++) { // 1. CharPosition bleibt ! + Line[i]-=(i-1)*(BoxRest) /(nChars-1); + } + R->ChrXP=UmbWdt; + Line[nChars+1]=UmbWdt; + } + } + + if (!AbsEnd) { + do { // Leerzeichen weglesen + (*WErec)=(*R); + c=GetTextChar(TBuf,R->Index,Atr0,R->Attrib,NoTrenn,FALSE); + nChars++; + Line[nChars]=R->ChrXP; + cLine[nChars]=c; + } while (c==' '); + if (c!=' ' && c!=AbsatzEnd && c!=TextEnd) { + nChars--; + (*R)=(*WErec); + } + } + + if (AbsEnd && nChars<MaxLineChars) { // Ausrichten, statt Blocksatz aber linksbuendig + if (Just==3) Just=0; + nChars++; Line[nChars]=R->ChrXP; // Damit AbsatzEnde auch weggelesen wird + Line[nChars+1]=R->ChrXP; // denn die Breite von CR oder #0 ist nun mal sehr klein + if (TBuf[R->Index-1]!=AbsatzEnd && TBuf[R->Index-1]!=TextEnd) { + c=GetTextChar(TBuf,R->Index,Atr0,R->Attrib,NoTrenn,FALSE); // Kleine Korrektur. Notig, wenn nur 1 Wort in + } + } + + BoxRest=AdjWdt-R->ChrXP; + if (TextFit) Just=THJustLeft; + + switch (Just) { + case THJustLeft: break; // Links + case THJustCenter: { + BoxRest=BoxRest /2; // Mitte + for (i=1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; + } break; + case THJustRight: { // Rechts + for (i=1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; + } break; + case THJustDrvOut: + case THJustBlock: { // Block und Austreibend + re=nChars; + if (Just==THJustDrvOut) re--; + while (re>=1 && (cLine[re]==' ' || cLine[re]==TextEnd || cLine[re]==AbsatzEnd)) re--; + li=1; + while (li<=re && (cLine[li]==' ' || cLine[li]==TextEnd || cLine[li]==AbsatzEnd)) li++; + if (Just==THJustDrvOut) BoxRest=AdjWdt-Line[re+1]; + + j=0; // Anzahl der Spaces ermitteln + for (i=li;i<=re;i++) { + if (cLine[i]==' ') { + j++; + } + } + + if (j==0) { // nur 1 Wort ? -> Strecken ! + for (i=li+1;i<=re;i++) { // von links nach rechts + Line[i]=Line[i]+MulDiv(i-li,BoxRest,re-li+1-1); + } + } else { + k=0; h=0; + for (i=li;i<=re;i++) { // j Spaces aufbohren ! + if (cLine[i]==' ') { // Space gefunden ! + k++; + h=MulDiv(k,BoxRest,j); + } + Line[i]=Line[i]+h; + } + } + for (i=re+1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; // und den Rest anpassen + Line[nChars+1]=AdjWdt; + } break; + case THJustLocked: { //Gesperrt + re=nChars-1; + while (re>=1 && (cLine[re]==' ' || cLine[re]==TextEnd || cLine[re]==AbsatzEnd)) re--; + li=1; + while (li<=re && (cLine[li]==' ' || cLine[li]==TextEnd || cLine[li]==AbsatzEnd)) li++; + BoxRest=AdjWdt-Line[re+1]; + for (i=li+1;i<=re;i++) { // Strecken von links nach rechts + Line[i]=Line[i]+MulDiv(i-li,BoxRest,re-li+1-1); + } + for (i=re+1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; // und den Rest anpassen + Line[nChars+1]=AdjWdt; + } break; + } + Index=R->Index; + AktAtr=R->Attrib; + delete R; + delete R0; + delete WErec; + delete WErec0; + delete TRrec; +} + + + +// End of Absatz.Pas +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// DrawText.Pas + +void DrawChar(OutputDevice& rOut, UCHAR c, ObjTextType T, PointType Pos, USHORT DrehWink, + USHORT FitXMul, USHORT FitXDiv, USHORT FitYMul, USHORT FitYDiv) +{ + SetTextContext(rOut,T,UpcasePossible(c),DrehWink,FitXMul,FitXDiv,FitYMul,FitYDiv); + if ((T.Schnitt & TextKaptBit)!=0 && UpcasePossible(c)) c=Upcase(c); + rtl::OUString s(reinterpret_cast<sal_Char*>(&c), 1, + RTL_TEXTENCODING_IBM_437); + rOut.DrawText( Point( Pos.x, Pos.y ), s ); +} + +/************************************************************************* +|* +|* TextType::Draw() +|* +*************************************************************************/ +void TextType::Draw(OutputDevice& rOut) +{ + if ((Flags & TextOutlBit)!=0) return; // Sourcetext fuer Outliner !! + + ObjTextType T1,T2; + USHORT Index1; + USHORT Index2; + UCHAR c = TextEnd; + USHORT l; // Anzahl der Zeichen in der Zeile + USHORT i; + short yPos0; + short xPos; + short yPos; + USHORT LF; + USHORT MaxGrad; + short xSize; + short xSAdj; + short ySize; + double sn,cs; + USHORT TopToBase; + BOOL Ende = 0; + USHORT lc; + BOOL LineFit; // FitSize.x=0? oder Flags -> jede Zeile stretchen + BOOL TextFit; + short* xLine; + UCHAR* cLine; // Buffer fuer FormatLine + USHORT FitXMul; + USHORT FitXDiv; + USHORT FitYMul; + USHORT FitYDiv; + BOOL Fehler; + UCHAR* Buf=Buffer; // Zeiger auf die Buchstaben + + pSgfFonts->ReadList(); + xLine=new short[ChrXPosArrSize]; + cLine=new UCHAR[CharLineSize]; + + TextFit=(Flags & TextFitBits)!=0; + LineFit=FALSE; + LineFit=((Flags & TextFitZBit)!=0); + if (TextFit && FitSize.x==0) LineFit=TRUE; + + if (DrehWink==0) { + sn=0.0; + cs=1.0; + } else { + sn=sin(double(DrehWink)*3.14159265359/18000); + cs=cos(double(DrehWink)*3.14159265359/18000); + } + + T1=T; Index1=0; yPos=0; xPos=0; + if (TextFit) { + ySize=Pos2.y-Pos1.y; + xSize=32000 /2; // Umbruch + xSAdj=Pos2.x-Pos1.x; // zum Ausrichten bei Zentriert/Blocksatz + //if (xSize<=0) { xSize=32000 /2; LineFit=TRUE; } + FitXMul=sal::static_int_cast< USHORT >(abs(Pos2.x-Pos1.x)); FitXDiv=FitSize.x; if (FitXDiv==0) FitXDiv=1; + FitYMul=sal::static_int_cast< USHORT >(abs(Pos2.y-Pos1.y)); FitYDiv=FitSize.y; if (FitYDiv==0) FitYDiv=1; + } else { + xSize=Pos2.x-Pos1.x; + xSAdj=xSize; + ySize=Pos2.y-Pos1.y; + FitXMul=1; FitXDiv=1; + FitYMul=1; FitYDiv=1; + } + if (xSize<0) xSize=0; + if (xSAdj<0) xSAdj=0; + + do { + T2=T1; Index2=Index1; + FormatLine(Buf,Index2,T,T2,xSize,xSAdj,xLine,l,sn,cs,cLine,LineFit); + Fehler=(Index2==Index1); + if (!Fehler) { + lc=GetLineFeed(Buf,Index1,T,T1,l,LF,MaxGrad); + if (TextFit) { + if (LineFit) FitXDiv=xLine[lc+1]; + if (FitXDiv>0) { + long Temp; + for (i=1;i<=l+1;i++) { + Temp=long(xLine[i])*long(FitXMul) /long(FitXDiv); + xLine[i]=short(Temp); + } + LF=MulDiv(LF,FitYMul,FitYDiv); + MaxGrad=MulDiv(MaxGrad,FitYMul,FitYDiv); + } else { + FitXDiv=1; // 0 gibts nicht + } + } + yPos0=yPos; + TopToBase=GetTopToBaseLine(MaxGrad); + yPos=yPos+TopToBase; + Ende=(yPos0+short(MulDiv(MaxGrad,CharTopToBtm,100))>ySize) && !TextFit; + if (!Ende) { + T2=T1; Index2=Index1; + i=1; + while (i<=l) { + c=GetTextCharConv(Buf,Index2,T,T2,l-i,FALSE); + long xp1,yp1; // wegen Overflowgefahr + PointType Pos; + xp1=long(Pos1.x)+xPos+long(xLine[i]); + yp1=long(Pos1.y)+yPos; + if (xp1>32000) xp1=32000; if (xp1<-12000) xp1=-12000; + if (yp1>32000) yp1=32000; if (yp1<-12000) yp1=-12000; + Pos.x=short(xp1); + Pos.y=short(yp1); + + if (DrehWink!=0) RotatePoint(Pos,Pos1.x,Pos1.y,sn,cs); + DrawChar(rOut,c,T2,Pos,DrehWink,FitXMul,FitXDiv,FitYMul,FitYDiv); + i++; + } // while i<=l + yPos=yPos0+LF; + T1=T2; Index1=Index2; // Fuer die naechste Zeile + } // if ObjMin.y+yPos<=Obj_Max.y + } // if !Fehler + } while (c!=TextEnd && !Ende && !Fehler); + delete[] cLine; + delete[] xLine; +} + +// End of DrawText.Pas +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// + +// nicht mehr benoetigt, da der Pointer nun extra gefuehrt wird +// (DEC Alpha hat naemlich 64Bit-Pointer!) +//UCHAR* TextType::GetBufPtr() +//{ +// ULONG Temp; +// Temp=ULONG(BufLo)+0x00010000*ULONG(BufHi); +// return (UCHAR*)Temp; +//} +// +//void TextType::SetBufPtr(UCHAR* Ptr) +//{ +// ULONG Temp=(ULONG)Ptr; +// BufLo=USHORT(Temp & 0x0000FFFF); +// BufHi=USHORT((Temp & 0xFFFF0000)>>16); +//} + +UINT32 ObjTextType::GetFont() +{ + return ULONG(FontLo)+0x00010000*ULONG(FontHi); +} + +void ObjTextType::SetFont(UINT32 FontID) +{ + FontLo=USHORT(FontID & 0x0000FFFF); + FontHi=USHORT((FontID & 0xFFFF0000)>>16); +} + + +///////////////////////////////////////////////////////////////////////////////// +// SGF.Ini lesen //////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +SgfFontOne::SgfFontOne() +{ + Next=NULL; + IFID=0; + Bold=FALSE; + Ital=FALSE; + Sans=FALSE; + Serf=FALSE; + Fixd=FALSE; + SVFamil=FAMILY_DONTKNOW; + SVChSet=RTL_TEXTENCODING_DONTKNOW; + SVWidth=40; +} + +void SgfFontOne::ReadOne( const rtl::OString& rID, ByteString& Dsc ) +{ + USHORT i,j,n; + rtl::OString s; + + if ( Dsc.Len() < 4 || ( Dsc.GetChar( 0 ) != '(' ) ) + return; + i=1; // Erster Buchstabe des IF-Fontnamen. Davor ist eine '(' + while ( i < Dsc.Len() && ( Dsc.GetChar( i ) !=')' ) ) + i++; + Dsc.Erase(0,i+1); // IF-Fontname loeschen inkl. () + + if ( Dsc.Len() < 2 || ( Dsc.GetChar( Dsc.Len() - 1 ) !=')' ) ) + return; + i=Dsc.Len()-2; // hier ist die ')' des SV-Fontnames + j=0; + while ( i > 0 && ( Dsc.GetChar( i ) != '(' ) ) + { + i--; + j++; + } + SVFName=String(Dsc,i+1,j,RTL_TEXTENCODING_IBM_437); // SV-Fontname rausholen + Dsc.Erase(i,j); + + IFID = (UINT32)rID.toInt32(); + n=Dsc.GetTokenCount(' '); + for (i=0;i<n;i++) + { + s = comphelper::string::getToken(Dsc, i,' '); + if (!s.isEmpty()) + { + s = s.toAsciiUpperCase(); + if (s.matchL(RTL_CONSTASCII_STRINGPARAM("BOLD"))) Bold=sal_True; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("ITAL"))) Ital=sal_True; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("SERF"))) Serf=sal_True; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("SANS"))) Sans=sal_True; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("FIXD"))) Fixd=sal_True; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("ROMAN"))) SVFamil=FAMILY_ROMAN; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("SWISS"))) SVFamil=FAMILY_SWISS; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("MODERN"))) SVFamil=FAMILY_MODERN; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("SCRIPT"))) SVFamil=FAMILY_SCRIPT; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("DECORA"))) SVFamil=FAMILY_DECORATIVE; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("ANSI"))) SVChSet=RTL_TEXTENCODING_MS_1252; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("IBMPC"))) SVChSet=RTL_TEXTENCODING_IBM_850; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("MAC"))) SVChSet=RTL_TEXTENCODING_APPLE_ROMAN; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("SYMBOL"))) SVChSet=RTL_TEXTENCODING_SYMBOL; + else if (s.matchL(RTL_CONSTASCII_STRINGPARAM("SYSTEM"))) SVChSet = osl_getThreadTextEncoding(); + else if (comphelper::string::isdigitAsciiString(s) ) SVWidth=sal::static_int_cast< sal_uInt16 >(s.toInt32()); + } + } +} + +///////////////////////////////////////////////////////////////////////////////// + +SgfFontLst::SgfFontLst() +{ + pList=NULL; + Last=NULL; + LastID=0; + LastLn=NULL; + Tried=FALSE; +} + +SgfFontLst::~SgfFontLst() +{ + RausList(); +} + +void SgfFontLst::RausList() +{ + SgfFontOne* P; + SgfFontOne* P1; + P=pList; + while (P!=NULL) { + P1=P->Next; + delete P; + P=P1; + } + pList=NULL; + Last=NULL; + Tried=FALSE; + LastID=0; + LastLn=NULL; +} + +void SgfFontLst::AssignFN(const String& rFName) +{ FNam=rFName; } + +void SgfFontLst::ReadList() +{ + if (!Tried) { + Tried=TRUE; + LastID=0; + LastLn=NULL; + SgfFontOne* P,P1; + Config aCfg(FNam); + aCfg.SetGroup("SGV Fonts fuer StarView"); + USHORT Anz=aCfg.GetKeyCount(); + USHORT i; + ByteString FID,Dsc; + + for (i=0;i<Anz;i++) + { + FID = comphelper::string::remove(aCfg.GetKeyName(i), ' '); + Dsc = aCfg.ReadKey( i ); + if ( comphelper::string::isdigitAsciiString(FID) ) + { + P=new SgfFontOne; // neuer Eintrag + if (Last!=NULL) Last->Next=P; else pList=P; Last=P; // einklinken + P->ReadOne(FID,Dsc); // und Zeile interpretieren + } + } + } +} + +SgfFontOne* SgfFontLst::GetFontDesc(UINT32 ID) +{ + if (ID!=LastID) { + SgfFontOne* P; + P=pList; + while (P!=NULL && P->IFID!=ID) P=P->Next; + LastID=ID; + LastLn=P; + } + return LastLn; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |