LCOV - code coverage report
Current view: top level - vcl/source/filter - sgvtext.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 21 591 3.6 %
Date: 2014-04-11 Functions: 4 30 13.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include "sal/config.h"
      21             : 
      22             : #include <boost/static_assert.hpp>
      23             : #include <osl/thread.h>
      24             : #include <rtl/math.h>
      25             : #include <comphelper/string.hxx>
      26             : #include <tools/config.hxx>
      27             : #include <vcl/graphicfilter.hxx>
      28             : #include "sgffilt.hxx"
      29             : #include "sgfbram.hxx"
      30             : #include "sgvmain.hxx"
      31             : #include <boost/scoped_array.hpp>
      32             : 
      33             : extern SgfFontLst* pSgfFonts;
      34             : 
      35             : #ifndef abs
      36             : #define abs(x) ((x)<0 ? -(x) : (x))
      37             : #endif
      38             : 
      39             : //  Limitations:  only grey shadows, 2D and with fixed distance.
      40             : // Start of AbsBase.Pas
      41             : 
      42             : // vvv special characters in text buffer vvv
      43             : #define  TextEnd        0 /* ^@ end of character sequence                       */
      44             : #define  HardSpace      6 /* ^F non-breaking space,' '                          */
      45             : #define  SoftTrennK    11 /* ^K character for k-c-switch for separation, 'k'    */
      46             : #define  AbsatzEnd     13 /* ^M new paragraph=CR                                */
      47             : #define  HardTrenn     16 /* ^P hard separator (not wrapped), '-'               */
      48             : #define  SoftTrennAdd  19 /* ^S extra-character, separates e.g. "schiff-fahrt"  */
      49             : #define  Escape        27 /* ^[ start of escape sequence                        */
      50             : #define  SoftTrenn     31 /* ^_ soft separator, '-' only end of line            */
      51             : #define  MaxEscValLen  8
      52             : #define  MaxEscLen     (MaxEscValLen+3)
      53             : 
      54             : // Escape sequences: [Esc]<Ident><Value>[Esc]  at least 4 characters
      55             : // Max length of value should be: 8 chars (7+sign). Therefore max. length
      56             : // of a escape sequence: 11 chars.
      57             : // Identifer:
      58             : 
      59             : #define  EscFont   'F' /* fontID, e.g. 92500 for CG Times                           */
      60             : #define  EscGrad   'G' /* font angle 1..255 for <<Pt-127<<Pt                        */
      61             : #define  EscBreit  'B' /* width 1..255% of the font angle                           */
      62             : #define  EscKaptS  'K' /* uppercase size 1..255% of the text angle                  */
      63             : #define  EscLFeed  'L' /* character spacing 1..32767% of max. text angle of the line*/
      64             :                         // or 1..32767 for 1..16383<<Pt absolute (if bit 15=1)
      65             : #define  EscSlant  'S' /* italic (angle) 1..8999 for 0.01deg..89.99deg              */
      66             : #define  EscVPos   'V' /* character vercial position 1..255 for <<Pt..127<<Pt       */
      67             : #define  EscZAbst  'Z' /* character spacing -128..127%                              */
      68             : #define  EscHJust  'A' /* H-justify  paragraph: left, cent, right, block, aligned, fixed (0..5)*/
      69             : 
      70             : #define  EscFarbe  'C' /* colour 0..7                                               */
      71             : #define  EscBFarb  'U' /* background colour 0..7                                    */
      72             : #define  EscInts   'I' /* colour intensity 0..100%                                  */
      73             : #define  EscMustr  'M' /* pattern 0..? incl. transp...                              */
      74             : #define  EscMFarb  'O' /* pattern colour 0..7                                       */
      75             : #define  EscMBFrb  'P' /* 2nd pattern colour 0..7                                   */
      76             : #define  EscMInts  'W' /* pattern intensity 0..7                                    */
      77             : 
      78             : #define  EscSMstr  'E' /* shadow pattern 0..? inkl. Transp...                       */
      79             : #define  EscSFarb  'R' /* shadow colour 0..7                                        */
      80             : #define  EscSBFrb  'T' /* 2nd shadow colour 0..7                                    */
      81             : #define  EscSInts  'Q' /* shadow intensity 0..7                                     */
      82             : 
      83             : #define  EscSXDst  'X' /* shadow offset X 0..100%                                   */
      84             : #define  EscSYDst  'Y' /* shadow offset Y 0..100%                                   */
      85             : #define  EscSDist  'D' /* shadow offset X-Y 0..100%                                 */
      86             : 
      87             : #define  EscBold   'f' /* bold                                                      */
      88             : #define  EscLSlnt  'l' /* L italic                                                  */
      89             : #define  EscRSlnt  'r' /* R italic                                                  */
      90             : #define  EscUndln  'u' /* underlined                                                */
      91             : #define  EscDbUnd  'p' /* double underlined                                         */
      92             : #define  EscKaptF  'k' /* uppercase flag                                            */
      93             : #define  EscStrik  'd' /* strikethrough                                             */
      94             : #define  EscDbStk  'e' /* double strikethrough                                      */
      95             : #define  EscSupSc  'h' /* superscript                                               */
      96             : #define  EscSubSc  't' /* subscript                                                 */
      97             : #define  Esc2DShd  's' /* 2D-shadow                                                 */
      98             : #define  Esc3DShd  'j' /* 3D-shadow                                                 */
      99             : #define  Esc4DShd  'i' /* 4D-shadow                                                 */
     100             : #define  EscEbShd  'b' /* embossed                                                  */
     101             : 
     102             : //  AllEscIdent =[EscFont, EscGrad, EscBreit,EscKaptS,EscLFeed,EscSlant,EscVPos, EscZAbst,EscHJust,
     103             : //                EscFarbe,EscBFarb,EscInts, EscMustr,EscMFarb,EscMBFrb,EscMInts,
     104             : //                EscSMstr,EscSFarb,EscSBFrb,EscSInts,EscSXDst,EscSYDst,EscSDist,
     105             : //                EscBold, EscLSlnt,EscRSlnt,EscUndln,EscDbUnd,EscKaptF,EscStrik,EscDbStk,
     106             : //                EscSupSc,EscSubSc,Esc2DShd,Esc3DShd,Esc4DShd];
     107             : // Justify muss spaetestens am Anfang des Absatzes stehen
     108             : #define  EscSet    '\x1e' /* set flag                                               */
     109             : #define  EscReset  '\x1f' /* reset flag                                             */
     110             : #define  EscDeflt  '\x11' /* set flag to default                                    */
     111             : #define  EscToggl  '\x1d' /* toggle flag                                            */
     112             : #define  EscNoFlg  0
     113             : #define  EscNoVal  -2147483647 /* -MaxLongInt */
     114             : 
     115             : #define  NoTrenn 0xFFFF   /* parameter value for 'Rest' of GetTextChar(), if separation should not occur */
     116             : #define  DoTrenn 0xFFFE   /* parameter value for 'Rest' of GetTextChar(), if separtion should occur      */
     117             : 
     118             : #define  MaxLineChars 1024
     119             : 
     120             : #define  ChrXPosArrSize (MaxLineChars+1+1)           /* 2k - start with 0 opposite to StarDraw */
     121             : #define  CharLineSize   (MaxLineChars+1+1)
     122             : 
     123             : #define  MinChar 32
     124             : #define  MaxChar 255
     125             : 
     126             : #define  CharTopToBase     100 /* due to quotes more as 75%         */
     127             : #define  CharTopToBtm      120 /* line height larger as text angle  */
     128             :                                // for Avanti-Bold 'ue' actually even 130%
     129             : 
     130             : // end of AbsBase.Pas
     131             : 
     132             : // Start of DefBase.Pas
     133             : 
     134             : #define  TextBoldBit  0x0001   /* bold                   */
     135             : #define  TextRSlnBit  0x0002   /* italic                 */
     136             : #define  TextUndlBit  0x0004   /* underline              */
     137             : #define  TextStrkBit  0x0008   /* strikethrough          */
     138             : #define  TextSupSBit  0x0010   /* superscript            */
     139             : #define  TextSubSBit  0x0020   /* subscript              */
     140             : #define  TextKaptBit  0x0040   /* capital                */
     141             : #define  TextLSlnBit  0x0080   /* left italic            */
     142             : #define  TextDbUnBit  0x0100   /* double underline       */
     143             : #define  TextDbStBit  0x0200   /* double strikethrough   */
     144             : #define  TextSh2DBit  0x0400   /* 2D-shadow         2.0  */
     145             : #define  TextSh3DBit  0x0800   /* 3D-shadow         2.0  */
     146             : #define  TextSh4DBit  0x1000   /* 4D-shadow         2.0  */
     147             : #define  TextShEbBit  0x2000   /* embossed-shadow   2.0  */
     148             : 
     149             : #define  THJustLeft     0x00
     150             : #define  THJustCenter   0x01
     151             : #define  THJustRight    0x02
     152             : #define  THJustBlock    0x03
     153             : #define  THJustDrvOut   0x04   /* Justified         formated */
     154             : #define  THJustLocked   0x05   /* J u s t   l  o  c  k  e  d */
     155             : 
     156             : #define  MaxCharSlant   4200   /* maximum 42deg italic ! */
     157             : 
     158             : // end of DefBase.Pas
     159             : 
     160           0 : bool CheckTextOutl(ObjAreaType& F, ObjLineType& L)
     161             : {
     162           0 :     return (F.FIntens!=L.LIntens) ||
     163           0 :            ((F.FFarbe!=L.LFarbe)   && (F.FIntens>0)) ||
     164           0 :            ((F.FBFarbe!=L.LBFarbe) && (F.FIntens<100));
     165             : }
     166             : 
     167             : // Start of Misc.Pas
     168             : 
     169           0 : short hPoint2Sgf(short a)
     170             : {
     171             :     long b;
     172           0 :     b=long(a)*127*SgfDpmm/(144*5);
     173           0 :     return short(b);
     174             : }
     175             : 
     176             : // End of Misc.Pas
     177             : 
     178             : // Start of AbsRead.Pas
     179             : 
     180             : // Function GetTopToBaseLine()  Function GetBaseLineToBtm()
     181             : //
     182             : // Calculate distance from ascender of line to baseline or from baseline to
     183             : // descender. All in SGF-units.
     184             : 
     185           0 : sal_uInt16 GetTopToBaseLine(sal_uInt16 MaxGrad)
     186             : {
     187             :     long ret;
     188           0 :     ret=long(MaxGrad)*long(CharTopToBase) /long(100);
     189           0 :     return sal_uInt16(ret);
     190             : }
     191             : 
     192             : // Function GetTextChar()   Function GetTextCharConv()
     193             : //
     194             : // Reads a character from textbuffer, in doing so escape sequences
     195             : // are evaluated and accordingly the input/output parameter AktAtr is set.
     196             : // Index is incremented accordingly.
     197             : // Parameter Rest should always contain the number of characters,
     198             : // the number of remaining characters in that line.
     199             : // Otherwise the hyphenation does not work. If the constand NoTrenn
     200             : // is used instaed, no hyphenation is done. To the contrary then
     201             : // constant DoTrenn triggers hyphenation where a soft-break is present.
     202             : //
     203             : // Soft separators are converted to a minus sign.
     204             : // On top GetTextCharConv() converts HardSpace and AbsatzEnde
     205             : // in spaces, including HardTrenner in minus signs. TextEnde is
     206             : // always returned as Char(0).
     207             : 
     208           0 : UCHAR ConvertTextChar(UCHAR c)
     209             : {
     210           0 :     if (c<32) {
     211           0 :         switch (c) {
     212           0 :             case HardSpace   : c=' '; break;
     213           0 :             case AbsatzEnd   : c=' '; break;
     214           0 :             case SoftTrenn   : c='-'; break;
     215           0 :             case HardTrenn   : c='-'; break;
     216           0 :             case SoftTrennK  : c='-'; break;
     217           0 :             case SoftTrennAdd: c='-';
     218             :         }
     219             :     }
     220           0 :     return c;
     221             : }
     222             : 
     223           0 : long ChgValue(long Def, long Min, long Max, UCHAR FlgVal, long NumVal)
     224             : {
     225           0 :     long r=0;
     226             : 
     227           0 :     if (FlgVal==EscDeflt) {
     228           0 :         r=Def;                          // return to default
     229             :     } else {
     230           0 :         if (NumVal!=EscNoVal) r=NumVal; // set non-breaking
     231             :     }
     232             : 
     233           0 :     if (Min!=0 || Max!=0) {
     234           0 :         if (r>Max) r=Max;
     235           0 :         if (r<Min) r=Min;
     236             :     }
     237           0 :     return r;
     238             : }
     239             : 
     240           0 : void ChgSchnittBit(sal_uInt16 Bit, sal_uInt16 Radio1, sal_uInt16 Radio2, sal_uInt16 Radio3,
     241             :                    UCHAR FlgVal, sal_uInt16 Schnitt0, sal_uInt16& Schnitt)
     242             : {
     243             :     sal_uInt16 All,Rad;
     244             : 
     245           0 :     Rad=Radio1 | Radio2 | Radio3;
     246           0 :     All=Bit | Rad;
     247             : 
     248           0 :     switch (FlgVal) {
     249           0 :         case EscSet  : Schnitt=(Schnitt & ~All) | Bit;              break;
     250           0 :         case EscReset: Schnitt=(Schnitt & ~All);                    break;
     251           0 :         case EscDeflt: Schnitt=(Schnitt & ~All) | (Schnitt0 & All); break;
     252           0 :         case EscToggl: Schnitt=(Schnitt & ~Rad) ^ Bit;
     253             :     }
     254           0 : }
     255             : 
     256           0 : UCHAR GetNextChar(UCHAR* TBuf, sal_uInt16 Index)
     257             : {
     258             :     sal_uInt16 Cnt;
     259           0 :     while (TBuf[Index]==Escape) {
     260           0 :         Index++;
     261           0 :         Cnt=0;
     262           0 :         while (TBuf[Index]!=Escape && Cnt<=MaxEscLen) {
     263           0 :             Index++; Cnt++; }
     264           0 :         Index++;
     265             :     }
     266           0 :     return TBuf[Index];
     267             : }
     268             : 
     269           0 : UCHAR ProcessOne(UCHAR* TBuf, sal_uInt16& Index,
     270             :                  ObjTextType& Atr0, ObjTextType& AktAtr,
     271             :                  bool ScanEsc)
     272             : {
     273             :     UCHAR c;
     274             :     UCHAR Ident;
     275             :     bool  Ende;
     276             :     bool  q;
     277             :     UCHAR FlgVal;
     278             :     long  NumVal;
     279             :     long  Sgn;
     280             :     short i;
     281             :     bool  EoVal;
     282             : 
     283           0 :     do {
     284           0 :         c=TBuf[Index]; Index++;
     285           0 :         Ende=(c!=Escape);
     286           0 :         if (!Ende) {
     287           0 :             c=TBuf[Index]; Index++;
     288           0 :             Ident=c;                          // remember identifier
     289           0 :             FlgVal=EscNoFlg;
     290           0 :             NumVal=EscNoVal;
     291           0 :             c=TBuf[Index]; Index++;            // value starts here
     292           0 :             if (c==EscSet || c==EscReset || c==EscDeflt || c==EscToggl) FlgVal=c; else {
     293           0 :                 if (c=='-') Sgn=-1; else Sgn=1;
     294           0 :                 if (c=='+' || c=='-') { c=TBuf[Index]; Index++; }
     295           0 :                 i=MaxEscValLen;
     296           0 :                 NumVal=0;
     297           0 :                 do {
     298           0 :                     NumVal=10*NumVal+c-'0';
     299           0 :                     EoVal=(TBuf[Index]<'0' || TBuf[Index]>'9');
     300           0 :                     if (!EoVal) { c=TBuf[Index]; Index++; }
     301           0 :                     i--;
     302           0 :                 } while (i>0 && !EoVal);
     303           0 :                 NumVal=Sgn*NumVal;
     304             :             }
     305           0 :             q=!CheckTextOutl(AktAtr.F,AktAtr.L);
     306             : 
     307           0 :             switch (Ident) {
     308           0 :                 case EscFont : AktAtr.SetFont(sal_uLong (ChgValue(Atr0.GetFont(),0,0          ,FlgVal,NumVal)));break;
     309           0 :                 case EscGrad : AktAtr.Grad   =sal_uInt16(ChgValue(Atr0.Grad,   2,2000         ,FlgVal,NumVal)); break;
     310           0 :                 case EscBreit: AktAtr.Breite =sal_uInt16(ChgValue(Atr0.Breite, 1,1000         ,FlgVal,NumVal)); break;
     311           0 :                 case EscKaptS: AktAtr.Kapit  =(sal_uInt8)(ChgValue(Atr0.Kapit,  1,255          ,FlgVal,NumVal)); break;
     312           0 :                 case EscLFeed: AktAtr.LnFeed =sal_uInt16(ChgValue(Atr0.LnFeed, 1,65535        ,FlgVal,NumVal)); break;
     313           0 :                 case EscSlant: AktAtr.Slant  =sal_uInt16(ChgValue(Atr0.Slant,  1,MaxCharSlant ,FlgVal,NumVal)); break;
     314           0 :                 case EscVPos : AktAtr.ChrVPos=char  (ChgValue(Atr0.ChrVPos,-128,127       ,FlgVal,NumVal)); break;
     315           0 :                 case EscZAbst: AktAtr.ZAbst  =(sal_uInt8)(ChgValue(Atr0.ZAbst,  1,255          ,FlgVal,NumVal)); break;
     316           0 :                 case EscHJust: AktAtr.Justify=(sal_uInt8)(ChgValue(Atr0.Justify & 0x0F,0,5     ,FlgVal,NumVal)); break;
     317           0 :                 case EscFarbe: { AktAtr.L.LFarbe =(sal_uInt8)(ChgValue(Atr0.L.LFarbe,0,7   ,FlgVal,NumVal)); if (q) AktAtr.F.FFarbe =AktAtr.L.LFarbe;  } break;
     318           0 :                 case EscBFarb: { AktAtr.L.LBFarbe=(sal_uInt8)(ChgValue(Atr0.L.LBFarbe,0,255,FlgVal,NumVal)); if (q) AktAtr.F.FBFarbe=AktAtr.L.LBFarbe; } break;
     319           0 :                 case EscInts : { AktAtr.L.LIntens=(sal_uInt8)(ChgValue(Atr0.L.LIntens,0,100,FlgVal,NumVal)); if (q) AktAtr.F.FIntens=AktAtr.L.LIntens; } break;
     320             : 
     321           0 :                 case EscMustr: { AktAtr.F.FMuster=sal_uInt16(ChgValue(Atr0.F.FMuster,0,65535,FlgVal,NumVal)); } break;
     322           0 :                 case EscMFarb: { AktAtr.F.FFarbe =(sal_uInt8)(ChgValue(Atr0.F.FFarbe,0,7   ,FlgVal,NumVal));   } break;
     323           0 :                 case EscMBFrb: { AktAtr.F.FBFarbe=(sal_uInt8)(ChgValue(Atr0.F.FBFarbe,0,255,FlgVal,NumVal));   } break;
     324           0 :                 case EscMInts: { AktAtr.F.FIntens=(sal_uInt8)(ChgValue(Atr0.F.FIntens,0,100,FlgVal,NumVal));   } break;
     325             : 
     326           0 :                 case EscSMstr: { AktAtr.ShdF.FMuster=sal_uInt16(ChgValue(Atr0.ShdF.FMuster,0,65535,FlgVal,NumVal)); } break;
     327           0 :                 case EscSFarb: { AktAtr.ShdL.LFarbe =(sal_uInt8)(ChgValue(Atr0.ShdL.LFarbe,0,7   ,FlgVal,NumVal)); AktAtr.ShdF.FFarbe =AktAtr.ShdL.LFarbe;  } break;
     328           0 :                 case EscSBFrb: { AktAtr.ShdL.LBFarbe=(sal_uInt8)(ChgValue(Atr0.ShdL.LBFarbe,0,255,FlgVal,NumVal)); AktAtr.ShdF.FBFarbe=AktAtr.ShdL.LBFarbe; } break;
     329           0 :                 case EscSInts: { AktAtr.ShdL.LIntens=(sal_uInt8)(ChgValue(Atr0.ShdL.LIntens,0,100,FlgVal,NumVal)); AktAtr.ShdF.FIntens=AktAtr.ShdL.LIntens; } break;
     330           0 :                 case EscSDist: { AktAtr.ShdVers.x=(short)ChgValue(Atr0.ShdVers.x,0,30000,FlgVal,NumVal); AktAtr.ShdVers.y=AktAtr.ShdVers.x; }            break;
     331           0 :                 case EscSXDst: { AktAtr.ShdVers.x=(short)ChgValue(Atr0.ShdVers.x,0,30000,FlgVal,NumVal); }  break;
     332           0 :                 case EscSYDst: { AktAtr.ShdVers.y=(short)ChgValue(Atr0.ShdVers.y,0,30000,FlgVal,NumVal); }  break;
     333             : 
     334           0 :                 case EscBold : ChgSchnittBit(TextBoldBit,0,0,0                              ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     335           0 :                 case EscRSlnt: ChgSchnittBit(TextRSlnBit,TextLSlnBit,0,0                    ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     336           0 :                 case EscUndln: ChgSchnittBit(TextUndlBit,TextDbUnBit,0,0                    ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     337           0 :                 case EscStrik: ChgSchnittBit(TextStrkBit,TextDbStBit,0,0                    ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     338           0 :                 case EscDbUnd: ChgSchnittBit(TextDbUnBit,TextUndlBit,0,0                    ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     339           0 :                 case EscDbStk: ChgSchnittBit(TextDbStBit,TextStrkBit,0,0                    ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     340           0 :                 case EscSupSc: ChgSchnittBit(TextSupSBit,TextSubSBit,0,0                    ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     341           0 :                 case EscSubSc: ChgSchnittBit(TextSubSBit,TextSupSBit,0,0                    ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     342           0 :                 case EscKaptF: ChgSchnittBit(TextKaptBit,0,0,0                              ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     343           0 :                 case EscLSlnt: ChgSchnittBit(TextLSlnBit,TextRSlnBit,0,0                    ,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     344           0 :                 case Esc2DShd: ChgSchnittBit(TextSh2DBit,TextSh3DBit,TextSh4DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     345           0 :                 case Esc3DShd: ChgSchnittBit(TextSh3DBit,TextSh2DBit,TextSh4DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     346           0 :                 case Esc4DShd: ChgSchnittBit(TextSh4DBit,TextSh2DBit,TextSh3DBit,TextShEbBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     347           0 :                 case EscEbShd: ChgSchnittBit(TextShEbBit,TextSh2DBit,TextSh3DBit,TextSh4DBit,FlgVal,Atr0.Schnitt,AktAtr.Schnitt); break;
     348             :             } //endcase
     349           0 :             if (TBuf[Index]==Escape) Index++;         // read 2nd escape }
     350             :         }
     351           0 :     } while (!Ende && !ScanEsc);
     352           0 :     if (!Ende) c=Escape;
     353           0 :     return c;
     354             : } // end of ProcessOne
     355             : 
     356           0 : UCHAR GetTextChar(UCHAR* TBuf, sal_uInt16& Index,
     357             :                   ObjTextType& Atr0, ObjTextType& AktAtr,
     358             :                   sal_uInt16 Rest, bool ScanEsc)
     359             : {
     360           0 :     UCHAR c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc);
     361           0 :     if (!ScanEsc) {
     362           0 :         if (c==SoftTrennAdd || c==SoftTrennK || c==SoftTrenn) {
     363           0 :             UCHAR nc=GetNextChar(TBuf,Index);
     364           0 :             UCHAR c0=c;
     365           0 :             if (Rest==0 || Rest==DoTrenn ||
     366           0 :                 nc==' ' || nc==AbsatzEnd || nc==TextEnd) c='-';
     367             :             else {
     368           0 :                 c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); // skip separator
     369           0 :                 if (c0==SoftTrennAdd) {
     370           0 :                     if (c>=32) c=ProcessOne(TBuf,Index,Atr0,AktAtr,ScanEsc); // skip another letter
     371             :                 }
     372             :             }
     373             :         }
     374           0 :         if ((Rest==1 || Rest==DoTrenn) && GetNextChar(TBuf,Index)==SoftTrennK) {
     375           0 :             if (c=='c') c='k';
     376           0 :             else if (c=='C') c='K';
     377             :         }
     378             :     }
     379           0 :     return c;
     380             : }
     381             : 
     382             :   // HardSpace and HardTrenn should be converted explicitely ! }
     383             :   // if AktAtr.Schnitt and TextKaptBit =TextKaptBit then c:=UpCase(c);(explizit) }
     384             : 
     385             :   // The separationmethod SoftTrennAdd assumes, the separating consonant }
     386             :   // is 3x present in TextBuf, e.g.: "schiff-fahrt".   }
     387             :   // If not separated then, "-f" is removed.        }
     388             : 
     389           0 : UCHAR GetTextCharConv(UCHAR* TBuf, sal_uInt16& Index,
     390             :                       ObjTextType& Atr0, ObjTextType& AktAtr,
     391             :                       sal_uInt16 Rest, bool ScanEsc)
     392             : {
     393             :     UCHAR c;
     394             : 
     395           0 :     c=GetTextChar(TBuf,Index,Atr0,AktAtr,Rest,ScanEsc);
     396           0 :     if (c<32) {
     397           0 :         switch (c) {
     398           0 :             case HardSpace   : c=' '; break;
     399           0 :             case AbsatzEnd   : c=' '; break;
     400           0 :             case HardTrenn   : c='-';
     401             :         }
     402             :     }
     403           0 :     return c;
     404             : }
     405             : 
     406             : // Function GetLineFeed()
     407             : //
     408             : // Required line spacing in SGF-Units. ChrVPos is taken into account.
     409             : // ======================================================================
     410           0 : sal_uInt16 GetLineFeed(UCHAR* TBuf, sal_uInt16 Index, ObjTextType Atr0, ObjTextType AktAtr,
     411             :                    sal_uInt16 nChar, sal_uInt16& LF, sal_uInt16& MaxGrad)
     412             : {
     413           0 :     UCHAR  c=0;
     414           0 :     bool   AbsEnd=false;
     415           0 :     sal_uLong  LF100=0;
     416           0 :     sal_uLong  MaxLF100=0;
     417           0 :     bool   LFauto=false;
     418           0 :     bool   First=true;
     419             :     sal_uInt16 Grad;
     420           0 :     sal_uInt16 i=0;
     421           0 :     sal_uInt16 r=1;
     422             : 
     423           0 :     MaxGrad=0;
     424           0 :     while (!AbsEnd && nChar>0) {
     425           0 :         nChar--;
     426           0 :         c=GetTextChar(TBuf,Index,Atr0,AktAtr,nChar,false);
     427           0 :         i++;
     428           0 :         AbsEnd=(c==TextEnd || c==AbsatzEnd);
     429           0 :         if (First || (!AbsEnd && c!=' ' && c!=HardTrenn)) {
     430           0 :             LFauto=(AktAtr.LnFeed & 0x8000)==0;
     431           0 :             LF100=AktAtr.LnFeed & 0x7FFF;
     432           0 :             if (LFauto) LF100=LF100*AktAtr.Grad; else LF100*=LF100;
     433           0 :             if (AktAtr.ChrVPos>0) LF100-=AktAtr.ChrVPos*100;
     434           0 :             if (LF100>MaxLF100) MaxLF100=LF100;
     435           0 :             Grad=AktAtr.Grad;
     436           0 :             if (AktAtr.ChrVPos>0) Grad=Grad-AktAtr.ChrVPos;
     437           0 :             if (Grad>MaxGrad) MaxGrad=Grad;
     438           0 :             First=false;
     439             :         }
     440           0 :         if (!AbsEnd && c!=' ') r=i;
     441             :     }
     442           0 :     MaxGrad=hPoint2Sgf(MaxGrad);
     443           0 :     if (MaxLF100<=4000) {  // otherwise overflow could occur
     444           0 :         LF=sal_uInt16(hPoint2Sgf(short(MaxLF100)) /100);
     445             :     } else {
     446           0 :         LF=sal_uInt16(hPoint2Sgf(short(MaxLF100) /100));
     447             :     }
     448             : 
     449           0 :     return r;
     450             : }
     451             : 
     452             : // End of AbsRead.Pas
     453             : 
     454             : // Start of iFont.Pas
     455             : 
     456             : #define SuperSubFact 60     /* superscript/subscript: 60% of text angle */
     457             : #define DefaultSpace 40     /* Default: space is 40% of text angle      */
     458             : 
     459           0 : sal_uInt16 SetTextContext(OutputDevice& rOut, ObjTextType& Atr, bool Kapt, sal_uInt16 Dreh,
     460             :                       sal_uInt16 FitXMul, sal_uInt16 FitXDiv, sal_uInt16 FitYMul, sal_uInt16 FitYDiv)
     461             : {
     462             :     SgfFontOne* pSgfFont; // Font from the IniFile
     463           0 :     Font   aFont;
     464           0 :     Color  aColor;
     465             :     sal_uLong  Grad;
     466             :     sal_uLong  Brei;
     467           0 :     OUString FNam;
     468           0 :     sal_uInt16 StdBrei=50;    // average line width in in % of text angle
     469           0 :     bool   bFit=(FitXMul!=1 || FitXDiv!=1 || FitYMul!=1 || FitYDiv!=1);
     470             : 
     471           0 :     pSgfFont = pSgfFonts->GetFontDesc(Atr.GetFont());
     472             : 
     473           0 :     if ( pSgfFont!=NULL )
     474             :     {
     475           0 :         FNam   =pSgfFont->SVFName;
     476           0 :         StdBrei=pSgfFont->SVWidth;
     477           0 :         if (pSgfFont->Fixd) aFont.SetPitch(PITCH_FIXED); else aFont.SetPitch(PITCH_VARIABLE);
     478           0 :         aFont.SetFamily(pSgfFont->SVFamil);
     479           0 :         aFont.SetCharSet(pSgfFont->SVChSet);
     480           0 :         aFont.SetName(FNam);
     481             :     }
     482             :     else
     483             :     {  // if not in Inifile, some fonts are hard coded here
     484           0 :         aFont.SetPitch(PITCH_VARIABLE);
     485           0 :         switch (Atr.GetFont()) {
     486             :           case 92500: case 92501: case 92504: case 92505:
     487             :           {
     488             : #if defined(WNT)
     489             :               FNam = "Times New Roman";  // CG Times is Times New Roman in Windows
     490             : #else
     491           0 :               FNam = "Times";            // otherwise just Times
     492             : #endif
     493           0 :               StdBrei=40;
     494           0 :               aFont.SetFamily(FAMILY_ROMAN);
     495           0 :           } break;
     496             :           case 94021: case 94022: case 94023: case 94024: {
     497             : #if defined(WNT)
     498             :               FNam = "Arial";            // Univers is Arial in Windows
     499             : #else
     500           0 :               FNam = "Helvetica";        // otherwise Helvetica
     501             : #endif
     502           0 :               aFont.SetFamily(FAMILY_SWISS);
     503           0 :               StdBrei=47;
     504           0 :           } break;
     505             :           case 93950: case 93951: case 93952: case 93953: {
     506             : #if defined(WNT)
     507             :               FNam = "Courier New";      // The vector-Courierfont is called Courier New in Windows
     508             : #else
     509           0 :               FNam = "Courier";          // otherwise Courier remains Courier
     510             : #endif
     511           0 :               aFont.SetFamily(FAMILY_ROMAN);
     512           0 :               aFont.SetPitch(PITCH_FIXED);
     513           0 :           } break;
     514           0 :           default: FNam = "Helvetica";
     515             :         }
     516           0 :         aFont.SetName(FNam);
     517             :         //aFont.SetCharSet(CHARSET_SYSTEM);
     518             :     }
     519             : 
     520           0 :     Grad=sal_uLong(Atr.Grad);
     521           0 :     if ((Atr.Schnitt & TextKaptBit) !=0 && Kapt) Grad=Grad*sal_uLong(Atr.Kapit)/100;
     522           0 :     if ((Atr.Schnitt & TextSupSBit) !=0 || (Atr.Schnitt & TextSubSBit) !=0) Grad=Grad*SuperSubFact/100;
     523           0 :     Brei=Grad;
     524           0 :     if (Atr.Breite!=100 || bFit) {
     525           0 :         if (bFit) {
     526           0 :             Grad=Grad*sal_uLong(FitYMul)/sal_uLong(FitYDiv);
     527           0 :             Brei=Brei*sal_uLong(FitXMul)/sal_uLong(FitXDiv);
     528             :         }
     529           0 :         Brei=Brei*sal_uLong(Atr.Breite)/100;
     530           0 :         Brei=Brei*sal_uLong(StdBrei)/100;
     531           0 :         aFont.SetSize(Size(hPoint2Sgf(sal_uInt16(Brei)),hPoint2Sgf(sal_uInt16(Grad))));
     532             :     } else {
     533           0 :         aFont.SetSize(Size(0,hPoint2Sgf(sal_uInt16(Grad))));
     534             :     }
     535             : 
     536           0 :     aColor=Sgv2SvFarbe(Atr.L.LFarbe,Atr.L.LBFarbe,Atr.L.LIntens); aFont.SetColor(aColor);
     537           0 :     aColor=Sgv2SvFarbe(Atr.F.FFarbe,Atr.F.FBFarbe,Atr.F.FIntens); aFont.SetFillColor(aColor);
     538           0 :     aFont.SetTransparent(true);
     539           0 :     aFont.SetAlign(ALIGN_BASELINE);
     540             : 
     541           0 :     Dreh/=10; Dreh=3600-Dreh; if (Dreh==3600) Dreh=0;
     542           0 :     aFont.SetOrientation(Dreh);
     543             : 
     544           0 :     if ((Atr.Schnitt & TextBoldBit) !=0) aFont.SetWeight(WEIGHT_BOLD);
     545           0 :     if ((Atr.Schnitt & TextRSlnBit) !=0) aFont.SetItalic(ITALIC_NORMAL);
     546           0 :     if ((Atr.Schnitt & TextUndlBit) !=0) aFont.SetUnderline(UNDERLINE_SINGLE);
     547           0 :     if ((Atr.Schnitt & TextDbUnBit) !=0) aFont.SetUnderline(UNDERLINE_DOUBLE);
     548           0 :     if ((Atr.Schnitt & TextStrkBit) !=0) aFont.SetStrikeout(STRIKEOUT_SINGLE);
     549           0 :     if ((Atr.Schnitt & TextDbStBit) !=0) aFont.SetStrikeout(STRIKEOUT_DOUBLE);
     550           0 :     if ((Atr.Schnitt & TextSh2DBit) !=0) aFont.SetShadow(true);
     551           0 :     if ((Atr.Schnitt & TextSh3DBit) !=0) aFont.SetShadow(true);
     552           0 :     if ((Atr.Schnitt & TextSh4DBit) !=0) aFont.SetShadow(true);
     553           0 :     if ((Atr.Schnitt & TextShEbBit) !=0) aFont.SetShadow(true);
     554           0 :     if (CheckTextOutl(Atr.F,Atr.L)) aFont.SetOutline(true);
     555             : 
     556           0 :     if (aFont!=rOut.GetFont()) rOut.SetFont(aFont);
     557             : 
     558           0 :     return 0;
     559             : }
     560             : 
     561             : // iFont.Pas
     562             : 
     563             : // Start of Absatz.Pas
     564             : 
     565             : struct ProcChrSta {
     566             :     sal_uInt16 Index;
     567             :     sal_uInt16 ChrXP;
     568             :     UCHAR  OutCh;
     569             :     bool   Kapt;
     570             :     ObjTextType Attrib;
     571             : };
     572             : 
     573           0 : void InitProcessCharState(ProcChrSta& State, ObjTextType& AktAtr, sal_uInt16 IndexA)
     574             : {
     575           0 :     State.Attrib=AktAtr;
     576           0 :     State.OutCh=0;
     577           0 :     State.Index=IndexA;
     578           0 :     State.ChrXP=0;
     579           0 :     State.Kapt=false;
     580           0 : }
     581             : 
     582           0 : bool UpcasePossible(UCHAR c)
     583             : {
     584           0 :     return ((c>='a' && c<='z') || c == 0xe4 || c == 0xf6 || c == 0xfc );
     585             : }
     586             : 
     587           0 : UCHAR Upcase(UCHAR c)
     588             : {
     589           0 :     if ((c>=(UCHAR)'a' && c<=(UCHAR)'z')) c=(c-(UCHAR)'a')+(UCHAR)'A';
     590           0 :     else if ( c == 0xe4 ) c = 0xc4;
     591           0 :     else if ( c == 0xf6 ) c = 0xd6;
     592           0 :     else if ( c == 0xfc ) c = 0xdc;
     593           0 :     return c;
     594             : }
     595             : 
     596           0 : sal_uInt16 GetCharWidth(OutputDevice& rOut, UCHAR c)
     597             : {
     598             :     sal_uInt16 ChrWidth;
     599             : 
     600           0 :     if (c==' ')
     601             :     {
     602           0 :         ChrWidth=(sal_uInt16)rOut.GetTextWidth( OUString('A') );
     603           0 :         if (rOut.GetFont().GetPitch()!=PITCH_FIXED) {
     604           0 :             ChrWidth=MulDiv(ChrWidth,DefaultSpace,100);
     605             :         }
     606             :     }
     607             :     else
     608             :     {
     609             :          // with MaxChar == 255 c cannot be greater than MaxChar
     610             :          // assert if MaxChar is ever changed
     611             :         BOOST_STATIC_ASSERT( MaxChar == 255 );
     612             :         BOOST_STATIC_ASSERT(sizeof(UCHAR) == 1);
     613           0 :         if (c>=MinChar /*&& c<=MaxChar*/)
     614             :         {
     615           0 :             ChrWidth=(sal_uInt16)rOut.GetTextWidth(OUString(reinterpret_cast<sal_Char*>(&c), 1, RTL_TEXTENCODING_IBM_437));
     616             :         }
     617             :         else
     618             :         {
     619           0 :             ChrWidth=(sal_uInt16)rOut.GetTextWidth(OUString(static_cast<sal_Unicode>('A')));
     620             :         }
     621             :     }
     622           0 :     return ChrWidth;
     623             : }
     624             : 
     625           0 : UCHAR ProcessChar(OutputDevice& rOut, UCHAR* TBuf, ProcChrSta& R, ObjTextType& Atr0,
     626             :                   sal_uInt16& nChars, sal_uInt16 Rest,
     627             :                   short* Line, UCHAR* cLine)
     628             : {
     629           0 :     sal_uInt16       KernDist=0;       // value for kerning
     630             :     sal_uInt16       ChrWidth;
     631             :     UCHAR        c;
     632             :     bool         AbsEnd;
     633             : 
     634           0 :     c=GetTextChar(TBuf,R.Index,Atr0,R.Attrib,Rest,false); // tries to separate, if Rest contains appropriate value
     635             : 
     636           0 :     AbsEnd=(c==AbsatzEnd || c==TextEnd);
     637           0 :     if (!AbsEnd) {
     638           0 :         R.OutCh=ConvertTextChar(c); // from HardTrenn to '-', ...
     639           0 :         R.Kapt=(R.Attrib.Schnitt & TextKaptBit) !=0 && UpcasePossible(R.OutCh);
     640           0 :         if (R.Kapt) R.OutCh=Upcase(R.OutCh);
     641           0 :         SetTextContext(rOut,R.Attrib,R.Kapt,0,1,1,1,1);
     642             : 
     643           0 :         UCHAR c1 = (R.Kapt)?Upcase(c):c;
     644           0 :         ChrWidth=GetCharWidth(rOut,c1);
     645             : 
     646           0 :         if (R.Attrib.ZAbst!=100) { // special line distance ?
     647             :             sal_uLong Temp;
     648           0 :             Temp=sal_uLong(ChrWidth)*sal_uLong(R.Attrib.ZAbst)/100;
     649           0 :             ChrWidth=sal_uInt16(Temp);
     650             :         }
     651           0 :         nChars++;
     652           0 :         if (R.ChrXP>32000) R.ChrXP=32000;
     653           0 :         Line[nChars]=R.ChrXP-KernDist;
     654           0 :         cLine[nChars]=c;
     655           0 :         R.ChrXP+=ChrWidth-KernDist; // position of next character
     656             :     }
     657           0 :     return c;
     658             : }
     659             : 
     660           0 : void FormatLine(UCHAR* TBuf, sal_uInt16& Index, ObjTextType& Atr0, ObjTextType& AktAtr,
     661             :                 sal_uInt16 UmbWdt, sal_uInt16 AdjWdt,
     662             :                 short* Line, sal_uInt16& nChars,
     663             :                 double, double,
     664             :                 UCHAR* cLine, bool TextFit)
     665             : {
     666           0 :     VirtualDevice vOut;
     667             :     UCHAR        c,c0;
     668             :     UCHAR        ct;
     669             :     bool         First;               // first char ?
     670           0 :     sal_uInt8    Just = 0;            // paragraph format
     671             :     bool         Border;              // border of box reached ?
     672             :     bool         Border0;
     673             :     bool         AbsEnd;              // end of paragraph reached ?
     674           0 :     ProcChrSta*  R=new ProcChrSta;
     675           0 :     ProcChrSta*  R0=new ProcChrSta;
     676           0 :     ProcChrSta*  WErec=new ProcChrSta;
     677             :     sal_uInt16       WEnChar;
     678           0 :     ProcChrSta*  WErec0=new ProcChrSta;
     679             :     sal_uInt16       WEnChar0;
     680           0 :     ProcChrSta*  TRrec=new ProcChrSta;
     681             :     sal_uInt16       TRnChar;
     682             : 
     683             :     sal_uInt16       WordEndCnt;          // justify and separate
     684             :     bool         WordEnd;
     685             :     bool         Trenn;
     686             : 
     687             :     short        BoxRest;             // to crush and format
     688             :     sal_uInt16       i,j,k,h;
     689             :     sal_uInt16       re,li;
     690             : 
     691           0 :     vOut.SetMapMode(MapMode(MAP_10TH_MM,Point(),Fraction(1,4),Fraction(1,4)));
     692             : 
     693           0 :     nChars=0;
     694           0 :     SetTextContext(vOut,AktAtr,false,0,1,1,1,1);
     695           0 :     InitProcessCharState(*R,AktAtr,Index);
     696           0 :     (*R0)=(*R); (*WErec)=(*R); WEnChar=0; c0=0; Border0=false;
     697           0 :     Border=false; First=true;
     698           0 :     WordEndCnt=0;
     699             : 
     700           0 :     do {               // check how many words to on that line
     701           0 :         if (Border) c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,DoTrenn,Line,cLine);
     702           0 :         else        c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,NoTrenn,Line,cLine);
     703           0 :         AbsEnd=(c==AbsatzEnd || c==TextEnd);
     704             :         //if not AbsEnd then
     705             :         {
     706           0 :             if (First) {
     707           0 :                 Just=R->Attrib.Justify & 0x0F; // paragraph format remains, then at start
     708             :             }
     709           0 :             Border=R->ChrXP>UmbWdt;
     710           0 :             WordEnd=(AbsEnd || (c==' ')) && (c0!=' ') && (c0!=0);
     711           0 :             Trenn=c=='-';
     712           0 :             if (WordEnd && !Border0) {
     713           0 :                 WordEndCnt++;
     714           0 :                 (*WErec)=(*R0);
     715           0 :                 WEnChar=nChars-1;
     716             :             }
     717           0 :             if (Trenn && !Border) {
     718           0 :                 WordEndCnt++;
     719           0 :                 (*WErec)=(*R);
     720           0 :                 WEnChar=nChars;
     721             :             }
     722             :         }
     723           0 :         (*R0)=(*R); c0=c;
     724           0 :         Border0=Border;
     725           0 :         First=false;
     726           0 :         AbsEnd=AbsEnd || (nChars>=MaxLineChars);
     727           0 :     } while (!(AbsEnd || (Border && ((WordEndCnt>0) || WordEnd || Trenn))));
     728             : 
     729           0 :     if (Border) { // separate and crush
     730           0 :         (*WErec0)=(*WErec); WEnChar0=WEnChar;
     731           0 :         AbsEnd=false; c0=0;
     732           0 :         (*R)=(*WErec); nChars=WEnChar;
     733           0 :         (*TRrec)=(*R); TRnChar=nChars;
     734           0 :         Border0=false; Border=false;
     735           0 :         do {                // first check how many syllables fit
     736           0 :             ct=ProcessChar(vOut,TBuf,*TRrec,Atr0,TRnChar,DoTrenn,Line,cLine);
     737           0 :             c=ProcessChar(vOut,TBuf,*R,Atr0,nChars,NoTrenn,Line,cLine);
     738           0 :             AbsEnd=(ct==AbsatzEnd) || (ct==TextEnd) || (nChars>=MaxLineChars);
     739             : 
     740           0 :             Border=TRrec->ChrXP>UmbWdt;
     741           0 :             WordEnd=AbsEnd || ((AbsEnd || (c==' ')) && (c0!=' ') && (c0!=0));
     742           0 :             Trenn=ct=='-';
     743           0 :             if (WordEnd && (!Border0 || (WordEndCnt==0))) {
     744           0 :                 WordEndCnt++;
     745           0 :                 (*WErec)=(*R0);
     746           0 :                 if (AbsEnd) WEnChar=nChars; else WEnChar=nChars-1;
     747           0 :                 (*TRrec)=(*R); TRnChar=nChars;                       // to continue searching
     748             :             }
     749           0 :             if (Trenn && (!Border || (WordEndCnt==0))) {
     750           0 :                 WordEndCnt++;                       // remember we can separate here
     751           0 :                 (*WErec)=(*TRrec);
     752           0 :                 WEnChar=TRnChar;
     753           0 :                 (*TRrec)=(*R); TRnChar=nChars;      // continue searching
     754             :             }
     755           0 :             (*R0)=(*R); c0=c;
     756           0 :             Border0=Border;
     757           0 :             Border=R->ChrXP>UmbWdt;
     758           0 :         } while (!(AbsEnd || (Border && ((WordEndCnt>0) || WordEnd || Trenn))));
     759             : 
     760           0 :         while (WErec0->Index<WErec->Index) { // to assure Line[] matches }
     761           0 :             c=ProcessChar(vOut,TBuf,*WErec0,Atr0,WEnChar0,WEnChar-WEnChar0-1,Line,cLine);
     762             :         }
     763             : 
     764           0 :         (*R)=(*WErec); nChars=WEnChar;
     765             : 
     766           0 :         if (UmbWdt>=R->ChrXP) {
     767           0 :             BoxRest=UmbWdt-R->ChrXP;
     768             :         } else {                                       // crush together
     769           0 :             BoxRest=R->ChrXP-UmbWdt;                   // so much should be crushed
     770           0 :             for (i=2;i<=nChars;i++) {                  // first character position remains!
     771           0 :                 Line[i]-=(i-1)*(BoxRest) /(nChars-1);
     772             :             }
     773           0 :             R->ChrXP=UmbWdt;
     774           0 :             Line[nChars+1]=UmbWdt;
     775             :         }
     776             :     }
     777             : 
     778           0 :     if (!AbsEnd) {
     779           0 :         do {                                         // read empty characters
     780           0 :             (*WErec)=(*R);
     781           0 :             c=GetTextChar(TBuf,R->Index,Atr0,R->Attrib,NoTrenn,false);
     782           0 :             nChars++;
     783           0 :             Line[nChars]=R->ChrXP;
     784           0 :             cLine[nChars]=c;
     785             :         } while (c==' ');
     786           0 :         if (c!=' ' && c!=AbsatzEnd && c!=TextEnd) {
     787           0 :             nChars--;
     788           0 :             (*R)=(*WErec);
     789             :         }
     790             :     }
     791             : 
     792           0 :     if (AbsEnd && nChars<MaxLineChars) { // align, left aligned instead of block
     793           0 :         if (Just==3) Just=0;
     794           0 :         nChars++; Line[nChars]=R->ChrXP; // to assure AbsatzEnde is read
     795           0 :         Line[nChars+1]=R->ChrXP;         // as the width of CR or #0 is very small
     796           0 :         if (TBuf[R->Index-1]!=AbsatzEnd &&  TBuf[R->Index-1]!=TextEnd) {
     797           0 :             c=GetTextChar(TBuf,R->Index,Atr0,R->Attrib,NoTrenn,false); // small correction needed, if 1st word read
     798             :         }
     799             :     }
     800             : 
     801           0 :     BoxRest=AdjWdt-R->ChrXP;
     802           0 :     if (TextFit) Just=THJustLeft;
     803             : 
     804           0 :     switch (Just) {
     805           0 :         case THJustLeft: break;                                // left
     806             :         case THJustCenter: {
     807           0 :             BoxRest=BoxRest /2;                                // middel
     808           0 :             for (i=1;i<=nChars;i++) Line[i]=Line[i]+BoxRest;
     809           0 :         } break;
     810             :         case THJustRight: {                                    // right
     811           0 :             for (i=1;i<=nChars;i++) Line[i]=Line[i]+BoxRest;
     812           0 :         } break;
     813             :         case THJustDrvOut:
     814             :         case THJustBlock: {                                    // block and justified
     815           0 :             re=nChars;
     816           0 :             if (Just==THJustDrvOut) re--;
     817           0 :             while (re>=1 && (cLine[re]==' ' || cLine[re]==TextEnd || cLine[re]==AbsatzEnd)) re--;
     818           0 :             li=1;
     819           0 :             while (li<=re && (cLine[li]==' ' || cLine[li]==TextEnd || cLine[li]==AbsatzEnd)) li++;
     820           0 :             if (Just==THJustDrvOut) BoxRest=AdjWdt-Line[re+1];
     821             : 
     822           0 :             j=0;                        // get number of spaces
     823           0 :             for (i=li;i<=re;i++) {
     824           0 :                 if (cLine[i]==' ') {
     825           0 :                     j++;
     826             :                 }
     827             :             }
     828             : 
     829           0 :             if (j==0) {                        // only one word ?  -> strech !
     830           0 :                 for (i=li+1;i<=re;i++) {       // from left to right
     831           0 :                   Line[i]=Line[i]+MulDiv(i-li,BoxRest,re-li+1-1);
     832             :                 }
     833             :             } else {
     834           0 :                 k=0; h=0;
     835           0 :                 for (i=li;i<=re;i++) {          // j drill spaces !
     836           0 :                     if (cLine[i]==' ') {        // space found !
     837           0 :                         k++;
     838           0 :                         h=MulDiv(k,BoxRest,j);
     839             :                     }
     840           0 :                     Line[i]=Line[i]+h;
     841             :                 }
     842             :             }
     843           0 :             for (i=re+1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; // adapt the rest
     844           0 :             Line[nChars+1]=AdjWdt;
     845           0 :         } break;
     846             :         case THJustLocked: {                                    // locked out
     847           0 :             re=nChars-1;
     848           0 :             while (re>=1 && (cLine[re]==' ' || cLine[re]==TextEnd || cLine[re]==AbsatzEnd)) re--;
     849           0 :             li=1;
     850           0 :             while (li<=re && (cLine[li]==' ' || cLine[li]==TextEnd || cLine[li]==AbsatzEnd)) li++;
     851           0 :             BoxRest=AdjWdt-Line[re+1];
     852           0 :             for (i=li+1;i<=re;i++) {         // strech from left to right
     853           0 :                 Line[i]=Line[i]+MulDiv(i-li,BoxRest,re-li+1-1);
     854             :             }
     855           0 :             for (i=re+1;i<=nChars;i++) Line[i]=Line[i]+BoxRest; // adapt the rest
     856           0 :             Line[nChars+1]=AdjWdt;
     857           0 :         } break;
     858             :     }
     859           0 :     Index=R->Index;
     860           0 :     AktAtr=R->Attrib;
     861           0 :     delete R;
     862           0 :     delete R0;
     863           0 :     delete WErec;
     864           0 :     delete WErec0;
     865           0 :     delete TRrec;
     866           0 : }
     867             : 
     868             : // End of Absatz.Pas
     869             : 
     870             : // Start of DrawText.Pas
     871             : 
     872           0 : void DrawChar(OutputDevice& rOut, UCHAR c, ObjTextType T, PointType Pos, sal_uInt16 DrehWink,
     873             :               sal_uInt16 FitXMul, sal_uInt16 FitXDiv, sal_uInt16 FitYMul, sal_uInt16 FitYDiv)
     874             : {
     875           0 :     SetTextContext(rOut,T,UpcasePossible(c),DrehWink,FitXMul,FitXDiv,FitYMul,FitYDiv);
     876           0 :     if ((T.Schnitt & TextKaptBit)!=0 && UpcasePossible(c)) c=Upcase(c);
     877             :     OUString s(reinterpret_cast<const sal_Char*>(&c), 1,
     878           0 :         RTL_TEXTENCODING_IBM_437);
     879           0 :     rOut.DrawText( Point( Pos.x, Pos.y ), s );
     880           0 : }
     881             : 
     882           0 : void TextType::Draw(OutputDevice& rOut)
     883             : {
     884           0 :     if ((Flags & TextOutlBit)!=0) return;   // source text for Outliner !!
     885             : 
     886             :     ObjTextType T1,T2;
     887             :     sal_uInt16 Index1;
     888             :     sal_uInt16 Index2;
     889           0 :     UCHAR  c = TextEnd;
     890             :     sal_uInt16 l;                // number of characters on the line
     891             :     sal_uInt16 i;
     892             :     short  yPos0;
     893             :     short  xPos;
     894             :     short  yPos;
     895             :     sal_uInt16 LF;
     896             :     sal_uInt16 MaxGrad;
     897             :     short  xSize;
     898             :     short  xSAdj;
     899             :     short  ySize;
     900             :     double sn,cs;
     901             :     sal_uInt16 TopToBase;
     902           0 :     bool   Ende = false;
     903             :     sal_uInt16 lc;
     904             :     bool   TextFit;
     905           0 :     boost::scoped_array<short> xLine;
     906           0 :     boost::scoped_array<UCHAR> cLine;   // Buffer for FormatLine
     907             :     sal_uInt16 FitXMul;
     908             :     sal_uInt16 FitXDiv;
     909             :     sal_uInt16 FitYMul;
     910             :     sal_uInt16 FitYDiv;
     911             :     bool   Fehler;
     912           0 :     UCHAR* Buf=Buffer; // pointer to the letters
     913             : 
     914           0 :     pSgfFonts->ReadList();
     915           0 :     xLine.reset(new short[ChrXPosArrSize]);
     916           0 :     cLine.reset(new UCHAR[CharLineSize]);
     917             : 
     918           0 :     TextFit=(Flags & TextFitBits)!=0;
     919           0 :     bool LineFit=((Flags & TextFitZBit)!=0);  // FitSize.x=0? or flags -> strech each line
     920           0 :     if (TextFit && FitSize.x==0) LineFit=true;
     921             : 
     922           0 :     if (DrehWink==0) {
     923           0 :         sn=0.0;
     924           0 :         cs=1.0;
     925             :     } else {
     926           0 :         sn=sin(double(DrehWink)*3.14159265359/18000);
     927           0 :         cs=cos(double(DrehWink)*3.14159265359/18000);
     928             :     }
     929             : 
     930           0 :     T1=T; Index1=0; yPos=0; xPos=0;
     931           0 :     if (TextFit) {
     932           0 :         ySize=Pos2.y-Pos1.y;
     933           0 :         xSize=32000 /2;      // break
     934           0 :         xSAdj=Pos2.x-Pos1.x; // to align for center/block
     935             :         //if (xSize<=0) { xSize=32000 /2; LineFit=true; }
     936           0 :         FitXMul=sal::static_int_cast< sal_uInt16 >(abs(Pos2.x-Pos1.x)); FitXDiv=FitSize.x; if (FitXDiv==0) FitXDiv=1;
     937           0 :         FitYMul=sal::static_int_cast< sal_uInt16 >(abs(Pos2.y-Pos1.y)); FitYDiv=FitSize.y; if (FitYDiv==0) FitYDiv=1;
     938             :     } else {
     939           0 :         xSize=Pos2.x-Pos1.x;
     940           0 :         xSAdj=xSize;
     941           0 :         ySize=Pos2.y-Pos1.y;
     942           0 :         FitXMul=1; FitXDiv=1;
     943           0 :         FitYMul=1; FitYDiv=1;
     944             :     }
     945           0 :     if (xSize<0) xSize=0;
     946           0 :     if (xSAdj<0) xSAdj=0;
     947             : 
     948           0 :     do {
     949           0 :         T2=T1; Index2=Index1;
     950           0 :         FormatLine(Buf,Index2,T,T2,xSize,xSAdj,xLine.get(),l,sn,cs,cLine.get(),LineFit);
     951           0 :         Fehler=(Index2==Index1);
     952           0 :         if (!Fehler) {
     953           0 :             lc=GetLineFeed(Buf,Index1,T,T1,l,LF,MaxGrad);
     954           0 :             if (TextFit) {
     955           0 :                 if (LineFit) FitXDiv=xLine[lc+1];
     956           0 :                 if (FitXDiv>0) {
     957             :                     long Temp;
     958           0 :                     for (i=1;i<=l+1;i++) {
     959           0 :                         Temp=long(xLine[i])*long(FitXMul) /long(FitXDiv);
     960           0 :                         xLine[i]=short(Temp);
     961             :                     }
     962           0 :                     LF=MulDiv(LF,FitYMul,FitYDiv);
     963           0 :                     MaxGrad=MulDiv(MaxGrad,FitYMul,FitYDiv);
     964             :                 } else {
     965           0 :                     FitXDiv=1; // 0 does not exist
     966             :                 }
     967             :             }
     968           0 :             yPos0=yPos;
     969           0 :             TopToBase=GetTopToBaseLine(MaxGrad);
     970           0 :             yPos=yPos+TopToBase;
     971           0 :             Ende=(yPos0+short(MulDiv(MaxGrad,CharTopToBtm,100))>ySize) && !TextFit;
     972           0 :             if (!Ende) {
     973           0 :                 T2=T1; Index2=Index1;
     974           0 :                 i=1;
     975           0 :                 while (i<=l) {
     976           0 :                     c=GetTextCharConv(Buf,Index2,T,T2,l-i,false);
     977             :                     long xp1,yp1;       // due to overflow danger
     978             :                     PointType Pos;
     979           0 :                     xp1=long(Pos1.x)+xPos+long(xLine[i]);
     980           0 :                     yp1=long(Pos1.y)+yPos;
     981           0 :                     if (xp1>32000) xp1=32000; if (xp1<-12000) xp1=-12000;
     982           0 :                     if (yp1>32000) yp1=32000; if (yp1<-12000) yp1=-12000;
     983           0 :                     Pos.x=short(xp1);
     984           0 :                     Pos.y=short(yp1);
     985             : 
     986           0 :                     if (DrehWink!=0) RotatePoint(Pos,Pos1.x,Pos1.y,sn,cs);
     987           0 :                     DrawChar(rOut,c,T2,Pos,DrehWink,FitXMul,FitXDiv,FitYMul,FitYDiv);
     988           0 :                     i++;
     989             :                 } // while i<=l
     990           0 :                 yPos=yPos0+LF;
     991           0 :                 T1=T2; Index1=Index2; // for next line
     992             :             } // if ObjMin.y+yPos<=Obj_Max.y
     993             :         } // if !Fehler
     994           0 :     } while (c!=TextEnd && !Ende && !Fehler);
     995             : }
     996             : 
     997             : // End of DrawText.Pas
     998             : 
     999           0 : sal_uInt32 ObjTextType::GetFont()
    1000             : {
    1001           0 :     return sal_uLong(FontLo)+0x00010000*sal_uLong(FontHi);
    1002             : }
    1003             : 
    1004           0 : void ObjTextType::SetFont(sal_uInt32 FontID)
    1005             : {
    1006           0 :     FontLo=sal_uInt16(FontID & 0x0000FFFF);
    1007           0 :     FontHi=sal_uInt16((FontID & 0xFFFF0000)>>16);
    1008           0 : }
    1009             : 
    1010             : // SGF.Ini lesen
    1011           0 : SgfFontOne::SgfFontOne()
    1012             : {
    1013           0 :     Next=NULL;
    1014           0 :     IFID=0;
    1015           0 :     Bold=false;
    1016           0 :     Ital=false;
    1017           0 :     Sans=false;
    1018           0 :     Serf=false;
    1019           0 :     Fixd=false;
    1020           0 :     SVFamil=FAMILY_DONTKNOW;
    1021           0 :     SVChSet=RTL_TEXTENCODING_DONTKNOW;
    1022           0 :     SVWidth=40;
    1023           0 : }
    1024             : 
    1025           0 : void SgfFontOne::ReadOne( const OString& rID, OString& Dsc )
    1026             : {
    1027           0 :     if ( Dsc.getLength() < 4 || ( Dsc[0] != '(' ) )
    1028           0 :         return;
    1029           0 :     sal_Int32 i=1;   // first letter of  IF fontname. In front is a '('
    1030           0 :     while ( i < Dsc.getLength() && ( Dsc[i] !=')' ) )
    1031           0 :         i++;
    1032           0 :     Dsc = Dsc.copy(i+1);                                // delete IF fontname incl. ()
    1033             : 
    1034           0 :     if ( Dsc.getLength() < 2 || ( Dsc[Dsc.getLength() - 1] !=')' ) )
    1035           0 :         return;
    1036           0 :     i = Dsc.getLength()-2;                                // here is the ')' of the SV fontname
    1037           0 :     sal_Int32 j=0;
    1038           0 :     while ( i > 0 && ( Dsc[i] != '(' ) )
    1039             :     {
    1040           0 :         i--;
    1041           0 :         j++;
    1042             :     }
    1043           0 :     SVFName = OStringToOUString(Dsc.copy(i+1,j), RTL_TEXTENCODING_IBM_437); // retrieve SV fontname
    1044           0 :     Dsc = OStringBuffer(Dsc).remove(i,j).makeStringAndClear();
    1045             : 
    1046           0 :     IFID = (sal_uInt32)rID.toInt32();
    1047           0 :     sal_Int32 nTokenCount = comphelper::string::getTokenCount(Dsc, ' ');
    1048           0 :     for (sal_Int32 nIdx = 0; nIdx < nTokenCount; ++nIdx)
    1049             :     {
    1050           0 :         OString s(Dsc.getToken(nIdx, ' '));
    1051           0 :         if (!s.isEmpty())
    1052             :         {
    1053           0 :             s = s.toAsciiUpperCase();
    1054           0 :             if      (s.match("BOLD")) Bold=true;
    1055           0 :             else if (s.match("ITAL")) Ital=true;
    1056           0 :             else if (s.match("SERF")) Serf=true;
    1057           0 :             else if (s.match("SANS")) Sans=true;
    1058           0 :             else if (s.match("FIXD")) Fixd=true;
    1059           0 :             else if (s.match("ROMAN")) SVFamil=FAMILY_ROMAN;
    1060           0 :             else if (s.match("SWISS")) SVFamil=FAMILY_SWISS;
    1061           0 :             else if (s.match("MODERN")) SVFamil=FAMILY_MODERN;
    1062           0 :             else if (s.match("SCRIPT")) SVFamil=FAMILY_SCRIPT;
    1063           0 :             else if (s.match("DECORA")) SVFamil=FAMILY_DECORATIVE;
    1064           0 :             else if (s.match("ANSI")) SVChSet=RTL_TEXTENCODING_MS_1252;
    1065           0 :             else if (s.match("IBMPC")) SVChSet=RTL_TEXTENCODING_IBM_850;
    1066           0 :             else if (s.match("MAC")) SVChSet=RTL_TEXTENCODING_APPLE_ROMAN;
    1067           0 :             else if (s.match("SYMBOL")) SVChSet=RTL_TEXTENCODING_SYMBOL;
    1068           0 :             else if (s.match("SYSTEM")) SVChSet = osl_getThreadTextEncoding();
    1069           0 :             else if (comphelper::string::isdigitAsciiString(s) ) SVWidth=sal::static_int_cast< sal_uInt16 >(s.toInt32());
    1070             :         }
    1071           0 :     }
    1072             : }
    1073             : 
    1074           2 : SgfFontLst::SgfFontLst()
    1075             : {
    1076           2 :     pList=NULL;
    1077           2 :     Last=NULL;
    1078           2 :     LastID=0;
    1079           2 :     LastLn=NULL;
    1080           2 :     Tried=false;
    1081           2 : }
    1082             : 
    1083           4 : SgfFontLst::~SgfFontLst()
    1084             : {
    1085           2 :     RausList();
    1086           2 : }
    1087             : 
    1088           2 : void SgfFontLst::RausList()
    1089             : {
    1090             :     SgfFontOne* P;
    1091             :     SgfFontOne* P1;
    1092           2 :     P=pList;
    1093           4 :     while (P!=NULL) {
    1094           0 :         P1=P->Next;
    1095           0 :         delete P;
    1096           0 :         P=P1;
    1097             :     }
    1098           2 :     pList=NULL;
    1099           2 :     Last=NULL;
    1100           2 :     Tried=false;
    1101           2 :     LastID=0;
    1102           2 :     LastLn=NULL;
    1103           2 : }
    1104             : 
    1105           2 : void SgfFontLst::AssignFN(const OUString& rFName)
    1106           2 : {   FNam=rFName;   }
    1107             : 
    1108           0 : void SgfFontLst::ReadList()
    1109             : {
    1110           0 :     if (!Tried)
    1111             :     {
    1112           0 :         Tried=true;
    1113           0 :         LastID=0;
    1114           0 :         LastLn=NULL;
    1115           0 :         SgfFontOne* P,P1;
    1116           0 :         Config aCfg(FNam);
    1117           0 :         aCfg.SetGroup("SGV Fonts fuer StarView");
    1118           0 :         sal_uInt16 Anz=aCfg.GetKeyCount();
    1119             :         sal_uInt16 i;
    1120           0 :         OString FID;
    1121           0 :         OString Dsc;
    1122             : 
    1123           0 :         for (i=0;i<Anz;i++)
    1124             :         {
    1125           0 :             FID = comphelper::string::remove(aCfg.GetKeyName(i), ' ');
    1126           0 :             Dsc = aCfg.ReadKey( i );
    1127           0 :             if (comphelper::string::isdigitAsciiString(FID))
    1128             :             {
    1129           0 :                 P=new SgfFontOne;                                   // new entry
    1130           0 :                 if (Last!=NULL) Last->Next=P; else pList=P; Last=P; // link it
    1131           0 :                 P->ReadOne(FID,Dsc);                                // interpret line
    1132             :             }
    1133           0 :         }
    1134             :     }
    1135           0 : }
    1136             : 
    1137           0 : SgfFontOne* SgfFontLst::GetFontDesc(sal_uInt32 ID)
    1138             : {
    1139           0 :     if (ID!=LastID) {
    1140             :         SgfFontOne* P;
    1141           0 :         P=pList;
    1142           0 :         while (P!=NULL && P->IFID!=ID) P=P->Next;
    1143           0 :         LastID=ID;
    1144           0 :         LastLn=P;
    1145             :     }
    1146           0 :     return LastLn;
    1147             : }
    1148             : 
    1149             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10