build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / filter / sgvmain.cxx
blob8f57eac3b46c14f05b7e483edaf572ddb7218084
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <rtl/math.hxx>
21 #include <osl/endian.h>
22 #include <vcl/graph.hxx>
23 #include <tools/poly.hxx>
24 #include <tools/fract.hxx>
25 #include <vcl/graphicfilter.hxx>
26 #include "sgffilt.hxx"
27 #include "sgfbram.hxx"
28 #include "sgvmain.hxx"
29 #include "sgvspln.hxx"
30 #include <unotools/ucbstreamhelper.hxx>
32 // Restrictions:
34 // - area patterns are matched to the available ones in Starview.
35 // - line ends are always rounded in StarView and continue past the end of line.
36 // - line patterns are matched to the available ones in Starview.
37 // transparency/opacity is not taken into account
38 // - no rotated ellipses
40 // for font translation
41 SgfFontLst* pSgfFonts = nullptr;
43 // for circle kinds, text and rotated rectangles
44 void RotatePoint(PointType& P, sal_Int16 cx, sal_Int16 cy, double sn, double cs)
46 sal_Int16 dx,dy;
47 double x1,y1;
48 dx=P.x-cx;
49 dy=P.y-cy;
50 x1=dx*cs-dy*sn;
51 y1=dy*cs+dx*sn;
52 P.x=cx+sal_Int16(x1);
53 P.y=cy+sal_Int16(y1);
56 void RotatePoint(Point& P, sal_Int16 cx, sal_Int16 cy, double sn, double cs)
58 sal_Int16 dx,dy;
59 double x1,y1;
60 dx=(sal_Int16)(P.X()-cx);
61 dy=(sal_Int16)(P.Y()-cy);
62 x1=dx*cs-dy*sn;
63 y1=dy*cs+dx*sn;
64 P=Point(cx+sal_Int16(x1),cy+sal_Int16(y1));
67 sal_Int16 iMulDiv(sal_Int16 a, sal_Int16 Mul, sal_Int16 Div)
69 sal_Int32 Temp;
70 Temp=sal_Int32(a)*sal_Int32(Mul)/sal_Int32(Div);
71 return sal_Int16(Temp);
74 sal_uInt16 MulDiv(sal_uInt16 a, sal_uInt16 Mul, sal_uInt16 Div)
76 sal_uInt32 Temp;
77 Temp=sal_uInt32(a)*sal_uInt32(Mul)/sal_uInt32(Div);
78 return sal_uInt16(Temp);
81 // SgfFilterSDrw
83 void DtHdOverSeek(SvStream& rInp)
85 sal_uLong FPos=rInp.Tell();
86 FPos+=(sal_uLong)DtHdSize;
87 rInp.Seek(FPos);
90 PageType::PageType()
92 memset( this, 0, sizeof( PageType ) );
95 SvStream& ReadPageType(SvStream& rIStream, PageType& rPage)
97 sal_uInt64 const nOldPos(rIStream.Tell());
98 rIStream.ReadUInt32(rPage.Next);
99 rIStream.ReadUInt32(rPage.nList);
100 rIStream.ReadUInt32(rPage.ListEnd);
101 rIStream.ReadInt16(rPage.Paper.Size.x);
102 rIStream.ReadInt16(rPage.Paper.Size.y);
103 rIStream.ReadInt16(rPage.Paper.RandL);
104 rIStream.ReadInt16(rPage.Paper.RandR);
105 rIStream.ReadInt16(rPage.Paper.RandO);
106 rIStream.ReadInt16(rPage.Paper.RandU);
107 rIStream.ReadUChar(rPage.Paper.PColor);
108 rIStream.ReadUChar(rPage.Paper.PIntens);
109 rIStream.ReadCharAsBool(rPage.BorderClip);
110 rIStream.ReadUChar(rPage.StdPg);
111 rIStream.ReadInt16(rPage.U.x);
112 rIStream.ReadInt16(rPage.U.y);
113 for (int i = 0; i < 20; ++i)
115 rIStream.ReadInt16(rPage.HlpLnH[i]);
117 for (int i = 0; i < 20; ++i)
119 rIStream.ReadInt16(rPage.HlpLnV[i]);
121 rIStream.ReadUChar(rPage.LnAnzH);
122 rIStream.ReadUChar(rPage.LnAnzV);
123 for (int i = 0; i < 32; ++i)
125 rIStream.ReadUChar(rPage.PgName[i]);
127 assert(rIStream.GetError() || rIStream.Tell() == nOldPos + PageSize);
128 (void) nOldPos;
129 return rIStream;
132 void ReadObjLineType(SvStream & rInp, ObjLineType & rLine)
134 // reads 8 bytes
135 rInp.ReadUChar(rLine.LFarbe);
136 rInp.ReadUChar(rLine.LBFarbe);
137 rInp.ReadUChar(rLine.LIntens);
138 rInp.ReadUChar(rLine.LMuster);
139 rInp.ReadInt16(rLine.LMSize);
140 rInp.ReadInt16(rLine.LDicke);
143 void ReadObjAreaType(SvStream & rInp, ObjAreaType & rArea)
145 // reads 8 bytes
146 rInp.ReadUChar(rArea.FFarbe);
147 rInp.ReadUChar(rArea.FBFarbe);
148 rInp.ReadUChar(rArea.FIntens);
149 rInp.ReadUChar(rArea.FDummy1);
150 rInp.ReadInt16(rArea.FDummy2);
151 rInp.ReadUInt16(rArea.FMuster);
154 void ObjkOverSeek(SvStream& rInp, ObjkType& rObjk)
156 sal_uLong Siz;
157 Siz=(sal_uLong)rObjk.MemSize+rObjk.Last; // ObjSize+ObjAnhSize
158 rInp.Seek(rInp.Tell()+Siz);
161 SvStream& ReadObjkType(SvStream& rInp, ObjkType& rObjk, bool const isRewind = true)
163 // fileposition in stream is not changed!
164 sal_uInt64 const nOldPos = rInp.Tell();
165 rInp.ReadUInt32(rObjk.Last);
166 rInp.ReadUInt32(rObjk.Next);
167 rInp.ReadUInt16(rObjk.MemSize);
168 rInp.ReadInt16(rObjk.ObjMin.x);
169 rInp.ReadInt16(rObjk.ObjMin.y);
170 rInp.ReadInt16(rObjk.ObjMax.x);
171 rInp.ReadInt16(rObjk.ObjMax.y);
172 rInp.ReadUChar(rObjk.Art);
173 rInp.ReadUChar(rObjk.Layer);
174 assert(rInp.GetError() || rInp.Tell() == nOldPos + ObjkSize);
175 if (isRewind)
176 rInp.Seek(nOldPos);
177 return rInp;
179 SvStream& ReadStrkType(SvStream& rInp, StrkType& rStrk)
181 sal_uInt64 const nOldPos(rInp.Tell());
182 ReadObjkType(rInp, rStrk, false);
183 rInp.ReadUChar(rStrk.Flags);
184 rInp.ReadUChar(rStrk.LEnden);
185 ReadObjLineType(rInp, rStrk.L);
186 rInp.ReadInt16(rStrk.Pos1.x);
187 rInp.ReadInt16(rStrk.Pos1.y);
188 rInp.ReadInt16(rStrk.Pos2.x);
189 rInp.ReadInt16(rStrk.Pos2.y);
190 assert(rInp.GetError() || rInp.Tell() == nOldPos + StrkSize);
191 (void) nOldPos;
192 return rInp;
194 SvStream& ReadRectType(SvStream& rInp, RectType& rRect)
196 sal_uInt64 const nOldPos(rInp.Tell());
197 ReadObjkType(rInp, rRect, false);
198 rInp.ReadUChar(rRect.Flags);
199 rInp.ReadUChar(rRect.Reserve);
200 ReadObjLineType(rInp, rRect.L);
201 ReadObjAreaType(rInp, rRect.F);
202 rInp.ReadInt16(rRect.Pos1.x);
203 rInp.ReadInt16(rRect.Pos1.y);
204 rInp.ReadInt16(rRect.Pos2.x);
205 rInp.ReadInt16(rRect.Pos2.y);
206 rInp.ReadInt16(rRect.Radius);
207 rInp.ReadUInt16(rRect.RotationAngle);
208 rInp.ReadUInt16(rRect.Slant);
209 assert(rInp.GetError() || rInp.Tell() == nOldPos + RectSize);
210 (void) nOldPos;
211 return rInp;
213 SvStream& ReadPolyType(SvStream& rInp, PolyType& rPoly)
215 sal_uInt64 const nOldPos(rInp.Tell());
216 ReadObjkType(rInp, rPoly, false);
217 rInp.ReadUChar(rPoly.Flags);
218 rInp.ReadUChar(rPoly.LEnden);
219 ReadObjLineType(rInp, rPoly.L);
220 ReadObjAreaType(rInp, rPoly.F);
221 rInp.ReadUChar(rPoly.nPoints);
222 rInp.ReadUChar(rPoly.Reserve);
223 rInp.ReadUInt32(rPoly.SD_EckP);
224 assert(rInp.GetError() || rInp.Tell() == nOldPos + PolySize);
225 (void) nOldPos;
226 return rInp;
229 SvStream& ReadSplnType(SvStream& rInp, SplnType& rSpln)
231 sal_uInt64 const nOldPos(rInp.Tell());
232 ReadObjkType(rInp, rSpln, false);
233 rInp.ReadUChar(rSpln.Flags);
234 rInp.ReadUChar(rSpln.LEnden);
235 ReadObjLineType(rInp, rSpln.L);
236 ReadObjAreaType(rInp, rSpln.F);
237 rInp.ReadUChar(rSpln.nPoints);
238 rInp.ReadUChar(rSpln.Reserve);
239 rInp.ReadUInt32(rSpln.SD_EckP);
240 assert(rInp.GetError() || rInp.Tell() == nOldPos + SplnSize);
241 (void) nOldPos;
242 return rInp;
244 SvStream& ReadCircType(SvStream& rInp, CircType& rCirc)
246 sal_uInt64 const nOldPos(rInp.Tell());
247 ReadObjkType(rInp, rCirc, false);
248 rInp.ReadUChar(rCirc.Flags);
249 rInp.ReadUChar(rCirc.LEnden);
250 ReadObjLineType(rInp, rCirc.L);
251 ReadObjAreaType(rInp, rCirc.F);
252 rInp.ReadInt16(rCirc.Center.x);
253 rInp.ReadInt16(rCirc.Center.y);
254 rInp.ReadInt16(rCirc.Radius.x);
255 rInp.ReadInt16(rCirc.Radius.y);
256 rInp.ReadUInt16(rCirc.RotationAngle);
257 rInp.ReadUInt16(rCirc.StartAngle);
258 rInp.ReadUInt16(rCirc.RelAngle);
259 assert(rInp.GetError() || rInp.Tell() == nOldPos + CircSize);
260 (void) nOldPos;
261 return rInp;
263 SvStream& ReadTextType(SvStream& rInp, TextType& rText)
265 sal_uInt64 const nOldPos(rInp.Tell());
266 ReadObjkType(rInp, rText, false);
267 rInp.ReadUChar(rText.Flags);
268 rInp.ReadUChar(rText.Reserve);
269 ReadObjLineType(rInp, rText.T.L);
270 ReadObjAreaType(rInp, rText.T.F);
271 rInp.ReadUInt16(rText.T.FontLo);
272 rInp.ReadUInt16(rText.T.FontHi);
273 rInp.ReadUInt16(rText.T.Grad);
274 rInp.ReadUInt16(rText.T.Breite);
275 rInp.ReadUChar(rText.T.Justify);
276 rInp.ReadUChar(rText.T.Kapit);
277 rInp.ReadUInt16(rText.T.Schnitt);
278 rInp.ReadUInt16(rText.T.LnFeed);
279 rInp.ReadUInt16(rText.T.Slant);
280 rInp.ReadUChar(rText.T.ZAbst);
281 rInp.ReadSChar(rText.T.ChrVPos);
282 ReadObjLineType(rInp, rText.T.ShdL);
283 ReadObjAreaType(rInp, rText.T.ShdF);
284 rInp.ReadInt16(rText.T.ShdVers.x);
285 rInp.ReadInt16(rText.T.ShdVers.y);
286 rInp.ReadCharAsBool(rText.T.ShdAbs);
287 rInp.ReadCharAsBool(rText.T.NoSpc);
288 ReadObjAreaType(rInp, rText.T.BackF);
289 rInp.ReadInt16(rText.Pos1.x);
290 rInp.ReadInt16(rText.Pos1.y);
291 rInp.ReadInt16(rText.Pos2.x);
292 rInp.ReadInt16(rText.Pos2.y);
293 rInp.ReadInt16(rText.TopOfs);
294 rInp.ReadUInt16(rText.RotationAngle);
295 rInp.ReadUInt16(rText.BoxSlant);
296 rInp.ReadUInt16(rText.BufSize);
297 rInp.ReadUInt16(rText.BufLo);
298 rInp.ReadUInt16(rText.BufHi);
299 rInp.ReadUInt16(rText.ExtLo);
300 rInp.ReadUInt16(rText.ExtHi);
301 rInp.ReadInt16(rText.FitSize.x);
302 rInp.ReadInt16(rText.FitSize.y);
303 rInp.ReadInt16(rText.FitBreit);
304 assert(rInp.GetError() || rInp.Tell() == nOldPos + TextSize);
305 (void) nOldPos;
306 rText.Buffer=nullptr;
307 return rInp;
309 SvStream& ReadBmapType(SvStream& rInp, BmapType& rBmap)
311 sal_uInt64 const nOldPos(rInp.Tell());
312 ReadObjkType(rInp, rBmap, false);
313 rInp.ReadUChar(rBmap.Flags);
314 rInp.ReadUChar(rBmap.Reserve);
315 ReadObjAreaType(rInp, rBmap.F);
316 rInp.ReadInt16(rBmap.Pos1.x);
317 rInp.ReadInt16(rBmap.Pos1.y);
318 rInp.ReadInt16(rBmap.Pos2.x);
319 rInp.ReadInt16(rBmap.Pos2.y);
320 rInp.ReadUInt16(rBmap.RotationAngle);
321 rInp.ReadUInt16(rBmap.Slant);
322 for (int i = 0; i < 80; ++i)
324 rInp.ReadUChar(rBmap.Filename[i]);
326 rInp.ReadInt16(rBmap.PixSize.x);
327 rInp.ReadInt16(rBmap.PixSize.y);
328 static_assert(sizeof(enum GrafStat) == 4, "enum has unexpected size");
329 sal_uInt32 nTemp(0);
330 rInp.ReadUInt32(nTemp);
331 rBmap.Format = static_cast<GrafStat>(nTemp);
332 rInp.ReadUChar(rBmap.nPlanes);
333 rInp.ReadCharAsBool(rBmap.RawOut);
334 rInp.ReadCharAsBool(rBmap.InvOut);
335 rInp.ReadCharAsBool(rBmap.LightOut);
336 rInp.ReadUChar(rBmap.GrfFlg);
337 assert(rInp.GetError() || rInp.Tell() == nOldPos + BmapSize);
338 (void) nOldPos;
339 return rInp;
341 SvStream& ReadGrupType(SvStream& rInp, GrupType& rGrup)
343 sal_uInt64 const nOldPos(rInp.Tell());
344 ReadObjkType(rInp, rGrup, false);
345 rInp.ReadUChar(rGrup.Flags);
346 for (int i = 0; i < 13; ++i)
348 rInp.ReadUChar(rGrup.Name[i]);
350 rInp.ReadUInt16(rGrup.SbLo);
351 rInp.ReadUInt16(rGrup.SbHi);
352 rInp.ReadUInt16(rGrup.UpLo);
353 rInp.ReadUInt16(rGrup.UpHi);
354 rInp.ReadUInt16(rGrup.ChartSize);
355 rInp.ReadUInt32(rGrup.ChartPtr);
356 assert(rInp.GetError() || rInp.Tell() == nOldPos + GrupSize);
357 (void) nOldPos;
358 return rInp;
361 Color Sgv2SvFarbe(sal_uInt8 nFrb1, sal_uInt8 nFrb2, sal_uInt8 nInts)
363 sal_uInt16 r1=0,g1=0,b1=0,r2=0,g2=0,b2=0;
364 sal_uInt8 nInt2=100-nInts;
365 switch(nFrb1 & 0x07) {
366 case 0: r1=0xFF; g1=0xFF; b1=0xFF; break;
367 case 1: r1=0xFF; g1=0xFF; break;
368 case 2: g1=0xFF; b1=0xFF; break;
369 case 3: g1=0xFF; break;
370 case 4: r1=0xFF; b1=0xFF; break;
371 case 5: r1=0xFF; break;
372 case 6: b1=0xFF; break;
373 case 7: break;
375 switch(nFrb2 & 0x07) {
376 case 0: r2=0xFF; g2=0xFF; b2=0xFF; break;
377 case 1: r2=0xFF; g2=0xFF; break;
378 case 2: g2=0xFF; b2=0xFF; break;
379 case 3: g2=0xFF; break;
380 case 4: r2=0xFF; b2=0xFF; break;
381 case 5: r2=0xFF; break;
382 case 6: b2=0xFF; break;
383 case 7: break;
385 r1=(sal_uInt16)((sal_uInt32)r1*nInts/100+(sal_uInt32)r2*nInt2/100);
386 g1=(sal_uInt16)((sal_uInt32)g1*nInts/100+(sal_uInt32)g2*nInt2/100);
387 b1=(sal_uInt16)((sal_uInt32)b1*nInts/100+(sal_uInt32)b2*nInt2/100);
388 Color aColor( (sal_uInt8)r1, (sal_uInt8)g1, (sal_uInt8)b1 );
389 return aColor;
392 void SetLine(ObjLineType& rLine, OutputDevice& rOut)
394 if( 0 == ( rLine.LMuster & 0x07 ) )
395 rOut.SetLineColor();
396 else
397 rOut.SetLineColor( Sgv2SvFarbe(rLine.LFarbe,rLine.LBFarbe,rLine.LIntens) );
400 void SetArea(ObjAreaType& rArea, OutputDevice& rOut)
402 if( 0 == ( rArea.FMuster & 0x00FF ) )
403 rOut.SetFillColor();
404 else
405 rOut.SetFillColor( Sgv2SvFarbe( rArea.FFarbe,rArea.FBFarbe,rArea.FIntens ) );
408 void ObjkType::Draw(OutputDevice&)
412 void StrkType::Draw(OutputDevice& rOut)
414 SetLine(L,rOut);
415 rOut.DrawLine(Point(Pos1.x,Pos1.y),Point(Pos2.x,Pos2.y)); // !!!
418 void SgfAreaColorIntens(sal_uInt16 Muster, sal_uInt8 Col1, sal_uInt8 Col2, sal_uInt8 Int, OutputDevice& rOut)
420 ObjAreaType F;
421 F.FMuster=Muster;
422 F.FFarbe=Col2;
423 F.FBFarbe=Col1;
424 F.FIntens=Int;
425 SetArea(F,rOut);
428 void DrawSlideRect(sal_Int16 x1, sal_Int16 y1, sal_Int16 x2, sal_Int16 y2, ObjAreaType& F, OutputDevice& rOut)
430 sal_Int16 i,i0,b,b0;
431 sal_Int16 Int1,Int2;
432 sal_Int16 Col1,Col2;
433 // ClipMerk: HgdClipRec;
434 sal_Int16 cx,cy;
435 sal_Int16 MaxR;
436 sal_Int32 dx,dy;
438 rOut.SetLineColor();
439 if (x1>x2) { i=x1; x1=x2; x2=i; }
440 if (y1>y2) { i=y1; y1=y2; y2=i; }
441 Col1=F.FBFarbe & 0x87; Col2=F.FFarbe & 0x87;
442 Int1=100-F.FIntens; Int2=F.FIntens;
443 if (Int1==Int2) {
444 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
445 rOut.DrawRect(Rectangle(x1,y1,x2,y2));
446 } else {
447 b0=Int1;
448 switch (F.FBFarbe & 0x38) {
449 case 0x08: { // vertikal
450 i0=y1;
451 i=y1;
452 while (i<=y2) {
453 b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-y1) /(sal_Int32)(y2-y1+1));
454 if (b!=b0) {
455 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
456 rOut.DrawRect(Rectangle(x1,i0,x2,i-1));
457 i0=i; b0=b;
459 i++;
461 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
462 rOut.DrawRect(Rectangle(x1,i0,x2,y2));
463 } break;
464 case 0x28: { // horizontal
465 i0=x1;
466 i=x1;
467 while (i<=x2) {
468 b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-x1) /(sal_Int32)(x2-x1+1));
469 if (b!=b0) {
470 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
471 rOut.DrawRect(Rectangle(i0,y1,i-1,y2));
472 i0=i; b0=b;
474 i++;
476 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
477 rOut.DrawRect(Rectangle(i0,y1,x2,y2));
478 } break;
480 case 0x18: case 0x38: { // circle
481 vcl::Region ClipMerk=rOut.GetClipRegion();
482 double a;
484 rOut.SetClipRegion(vcl::Region(Rectangle(x1,y1,x2,y2)));
485 cx=(x1+x2) /2;
486 cy=(y1+y2) /2;
487 dx=x2-x1+1;
488 dy=y2-y1+1;
489 a=sqrt((double)(dx*dx+dy*dy));
490 MaxR=sal_Int16(a) /2 +1;
491 b0=Int2;
492 i0=MaxR; if (MaxR<1) MaxR=1;
493 i=MaxR;
494 while (i>=0) {
495 b=Int1+sal_Int16((sal_Int32(Int2-Int1)*sal_Int32(i)) /sal_Int32(MaxR));
496 if (b!=b0) {
497 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
498 rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
499 i0=i; b0=b;
501 i--;
503 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int1,rOut);
504 rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
505 rOut.SetClipRegion(ClipMerk);
506 } break; // circle
511 void RectType::Draw(OutputDevice& rOut)
513 if (L.LMuster!=0) L.LMuster=1; // no line separator here, only on or off
514 SetArea(F,rOut);
515 if (RotationAngle==0) {
516 if ((F.FBFarbe & 0x38)==0 || Radius!=0) {
517 SetLine(L,rOut);
518 rOut.DrawRect(Rectangle(Pos1.x,Pos1.y,Pos2.x,Pos2.y),Radius,Radius);
519 } else {
520 DrawSlideRect(Pos1.x,Pos1.y,Pos2.x,Pos2.y,F,rOut);
521 if (L.LMuster!=0) {
522 SetLine(L,rOut);
523 rOut.SetFillColor();
524 rOut.DrawRect(Rectangle(Pos1.x,Pos1.y,Pos2.x,Pos2.y));
527 } else {
528 Point aPts[4];
529 sal_uInt16 i;
530 double sn,cs;
531 sn=sin(double(RotationAngle)*3.14159265359/18000);
532 cs=cos(double(RotationAngle)*3.14159265359/18000);
533 aPts[0]=Point(Pos1.x,Pos1.y);
534 aPts[1]=Point(Pos2.x,Pos1.y);
535 aPts[2]=Point(Pos2.x,Pos2.y);
536 aPts[3]=Point(Pos1.x,Pos2.y);
537 for (i=0;i<4;i++) {
538 RotatePoint(aPts[i],Pos1.x,Pos1.y,sn,cs);
540 SetLine(L,rOut);
541 tools::Polygon aPoly(4,aPts);
542 rOut.DrawPolygon(aPoly);
546 void PolyType::Draw(OutputDevice& rOut)
548 if ((Flags & PolyClosBit) !=0) SetArea(F,rOut);
549 SetLine(L,rOut);
550 tools::Polygon aPoly(nPoints);
551 sal_uInt16 i;
552 for(i=0;i<nPoints;i++) aPoly.SetPoint(Point(EckP[i].x,EckP[i].y),i);
553 if ((Flags & PolyClosBit) !=0) {
554 rOut.DrawPolygon(aPoly);
555 } else {
556 rOut.DrawPolyLine(aPoly);
560 void SplnType::Draw(OutputDevice& rOut)
562 if ((Flags & PolyClosBit) !=0) SetArea(F,rOut);
563 SetLine(L,rOut);
564 tools::Polygon aPoly(0);
565 tools::Polygon aSpln(nPoints);
566 sal_uInt16 i;
567 for(i=0;i<nPoints;i++) aSpln.SetPoint(Point(EckP[i].x,EckP[i].y),i);
568 if ((Flags & PolyClosBit) !=0) {
569 Spline2Poly(aSpln,true,aPoly);
570 if (aPoly.GetSize()>0) rOut.DrawPolygon(aPoly);
571 } else {
572 Spline2Poly(aSpln,false,aPoly);
573 if (aPoly.GetSize()>0) rOut.DrawPolyLine(aPoly);
577 void DrawSlideCirc(sal_Int16 cx, sal_Int16 cy, sal_Int16 rx, sal_Int16 ry, ObjAreaType& F, OutputDevice& rOut)
579 sal_Int16 x1=cx-rx;
580 sal_Int16 y1=cy-ry;
581 sal_Int16 x2=cx+rx;
582 sal_Int16 y2=cy+ry;
584 sal_Int16 i,i0,b,b0;
585 sal_Int16 Int1,Int2;
586 sal_Int16 Col1,Col2;
588 rOut.SetLineColor();
589 Col1=F.FBFarbe & 0x87; Col2=F.FFarbe & 0x87;
590 Int1=100-F.FIntens; Int2=F.FIntens;
591 if (Int1==Int2) {
592 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
593 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
594 } else {
595 b0=Int1;
596 switch (F.FBFarbe & 0x38) {
597 case 0x08: { // vertical
598 vcl::Region ClipMerk=rOut.GetClipRegion();
599 i0=y1;
600 i=y1;
601 while (i<=y2) {
602 b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-y1) /(sal_Int32)(y2-y1+1));
603 if (b!=b0) {
604 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
605 rOut.SetClipRegion(vcl::Region(Rectangle(x1,i0,x2,i-1)));
606 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
607 i0=i; b0=b;
609 i++;
611 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
612 rOut.SetClipRegion(vcl::Region(Rectangle(x1,i0,x2,y2)));
613 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
614 rOut.SetClipRegion(ClipMerk);
615 } break;
616 case 0x28: { // horizontal
617 vcl::Region ClipMerk=rOut.GetClipRegion();
618 i0=x1;
619 i=x1;
620 while (i<=x2) {
621 b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-x1) /(sal_Int32)(x2-x1+1));
622 if (b!=b0) {
623 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
624 rOut.SetClipRegion(vcl::Region(Rectangle(i0,y1,i-1,y2)));
625 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
626 i0=i; b0=b;
628 i++;
630 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
631 rOut.SetClipRegion(vcl::Region(Rectangle(i0,y1,x2,y2)));
632 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
633 rOut.SetClipRegion(ClipMerk);
634 } break;
636 case 0x18: case 0x38: { // circle
637 sal_Int16 MaxR;
639 if (rx<1) rx=1;
640 if (ry<1) ry=1;
641 MaxR=rx;
642 b0=Int2;
643 i0=MaxR;
644 i=MaxR;
645 while (i>=0) {
646 b=Int1+sal_Int16((sal_Int32(Int2-Int1)*sal_Int32(i)) /sal_Int32(MaxR));
647 if (b!=b0) {
648 sal_Int32 temp=sal_Int32(i0)*sal_Int32(ry)/sal_Int32(rx);
649 sal_Int16 j0=sal_Int16(temp);
650 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
651 rOut.DrawEllipse(Rectangle(cx-i0,cy-j0,cx+i0,cy+j0));
652 i0=i; b0=b;
654 i--;
656 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int1,rOut);
657 rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
658 } break; // circle
663 void CircType::Draw(OutputDevice& rOut)
665 Rectangle aRect(Center.x-Radius.x,Center.y-Radius.y,Center.x+Radius.x,Center.y+Radius.y);
667 if (L.LMuster!=0) L.LMuster=1; // no line pattern here, only on or off
668 SetArea(F,rOut);
669 if ((Flags & 0x03)==CircFull) {
670 if ((F.FBFarbe & 0x38)==0) {
671 SetLine(L,rOut);
672 rOut.DrawEllipse(aRect);
673 } else {
674 DrawSlideCirc(Center.x,Center.y,Radius.x,Radius.y,F,rOut);
675 if (L.LMuster!=0) {
676 SetLine(L,rOut);
677 rOut.SetFillColor();
678 rOut.DrawEllipse(aRect);
681 } else {
682 PointType a,b;
683 Point aStrt,aEnde;
684 double sn,cs;
686 a.x=Center.x+Radius.x; a.y=Center.y; b=a;
687 sn=sin(double(StartAngle)*3.14159265359/18000);
688 cs=cos(double(StartAngle)*3.14159265359/18000);
689 RotatePoint(a,Center.x,Center.y,sn,cs);
690 sn=sin(double(StartAngle+RelAngle)*3.14159265359/18000);
691 cs=cos(double(StartAngle+RelAngle)*3.14159265359/18000);
692 RotatePoint(b,Center.x,Center.y,sn,cs);
693 if (Radius.x!=Radius.y) {
694 if (Radius.x<1) Radius.x=1;
695 if (Radius.y<1) Radius.y=1;
696 a.y = a.y - Center.y;
697 b.y = b.y - Center.y;
698 a.y=iMulDiv(a.y,Radius.y,Radius.x);
699 b.y=iMulDiv(b.y,Radius.y,Radius.x);
700 a.y = a.y + Center.y;
701 b.y = b.y + Center.y;
703 aStrt=Point(a.x,a.y);
704 aEnde=Point(b.x,b.y);
705 SetLine(L,rOut);
706 switch (Flags & 0x03) {
707 case CircArc : rOut.DrawArc(aRect,aEnde,aStrt); break;
708 case CircSect:
709 case CircAbsn: rOut.DrawPie(aRect,aEnde,aStrt); break;
714 void BmapType::Draw(OutputDevice& rOut)
716 //ifstream aInp;
717 sal_uInt16 nVersion;
718 OUString aStr(
719 reinterpret_cast< char const * >(&Filename[ 1 ]),
720 (sal_Int32)Filename[ 0 ], RTL_TEXTENCODING_UTF8 );
721 INetURLObject aFNam( aStr );
723 SvStream* pInp = ::utl::UcbStreamHelper::CreateStream( aFNam.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ );
724 if ( pInp )
726 unsigned char nSgfTyp = CheckSgfTyp( *pInp,nVersion);
727 switch(nSgfTyp) {
728 case SGF_BITIMAGE: {
729 GraphicFilter aFlt;
730 Graphic aGrf;
731 aFlt.ImportGraphic(aGrf,aFNam);
732 aGrf.Draw(&rOut,Point(Pos1.x,Pos1.y),Size(Pos2.x-Pos1.x,Pos2.y-Pos1.y));
733 } break;
734 case SGF_SIMPVECT: {
735 GDIMetaFile aMtf;
736 SgfVectXofs=Pos1.x;
737 SgfVectYofs=Pos1.y;
738 SgfVectXmul=Pos2.x-Pos1.x;
739 SgfVectYmul=Pos2.y-Pos1.y;
740 SgfVectXdiv=0;
741 SgfVectYdiv=0;
742 SgfVectScal=true;
743 SgfVectFilter(*pInp,aMtf);
744 SgfVectXofs=0;
745 SgfVectYofs=0;
746 SgfVectXmul=0;
747 SgfVectYmul=0;
748 SgfVectXdiv=0;
749 SgfVectYdiv=0;
750 SgfVectScal=false;
751 aMtf.Play(&rOut);
752 } break;
754 delete pInp;
758 sal_uInt32 GrupType::GetSubPtr()
760 return sal_uInt32(SbLo)+0x00010000*sal_uInt32(SbHi);
763 void DrawObjkList( SvStream& rInp, OutputDevice& rOut )
765 ObjkType aObjk;
766 sal_uInt16 nGrpCnt=0;
767 bool bEnd=false;
768 do {
769 ReadObjkType( rInp, aObjk );
770 if (!rInp.GetError()) {
771 switch(aObjk.Art) {
772 case ObjStrk: { StrkType aStrk; ReadStrkType( rInp, aStrk ); if (!rInp.GetError()) aStrk.Draw(rOut); } break;
773 case ObjRect: { RectType aRect; ReadRectType( rInp, aRect ); if (!rInp.GetError()) aRect.Draw(rOut); } break;
774 case ObjCirc: { CircType aCirc; ReadCircType( rInp, aCirc ); if (!rInp.GetError()) aCirc.Draw(rOut); } break;
775 case ObjText: {
776 TextType aText;
777 ReadTextType( rInp, aText );
778 if (!rInp.GetError()) {
779 aText.Buffer=new UCHAR[aText.BufSize+1]; // add one for LookAhead at CK-separation
780 rInp.ReadBytes(aText.Buffer, aText.BufSize);
781 if (!rInp.GetError()) aText.Draw(rOut);
782 delete[] aText.Buffer;
784 } break;
785 case ObjBmap: {
786 BmapType aBmap;
787 ReadBmapType( rInp, aBmap );
788 if (!rInp.GetError()) {
789 aBmap.Draw(rOut);
791 } break;
792 case ObjPoly: {
793 PolyType aPoly;
794 ReadPolyType( rInp, aPoly );
795 if (!rInp.GetError()) {
796 aPoly.EckP=new PointType[aPoly.nPoints];
797 for (int i = 0; i < aPoly.nPoints; ++i)
799 rInp.ReadInt16(aPoly.EckP[i].x);
800 rInp.ReadInt16(aPoly.EckP[i].y);
802 if (!rInp.GetError()) aPoly.Draw(rOut);
803 delete[] aPoly.EckP;
805 } break;
806 case ObjSpln: {
807 SplnType aSpln;
808 ReadSplnType( rInp, aSpln );
809 if (!rInp.GetError()) {
810 aSpln.EckP=new PointType[aSpln.nPoints];
811 for (int i = 0; i < aSpln.nPoints; ++i)
813 rInp.ReadInt16(aSpln.EckP[i].x);
814 rInp.ReadInt16(aSpln.EckP[i].y);
816 if (!rInp.GetError()) aSpln.Draw(rOut);
817 delete[] aSpln.EckP;
819 } break;
820 case ObjGrup: {
821 GrupType aGrup;
822 ReadGrupType( rInp, aGrup );
823 if (!rInp.GetError()) {
824 rInp.Seek(rInp.Tell()+aGrup.Last); // object appendix
825 if(aGrup.GetSubPtr()!=0) nGrpCnt++; // DrawObjkList(rInp,rOut );
827 } break;
828 default: {
829 aObjk.Draw(rOut); // object name on 2. Screen
830 ObjkOverSeek(rInp,aObjk); // to next object
833 } // if rInp
834 if (!rInp.GetError()) {
835 if (aObjk.Next==0) {
836 if (nGrpCnt==0) bEnd=true;
837 else nGrpCnt--;
839 } else {
840 bEnd=true; // read error
842 } while (!bEnd);
845 void SkipObjkList(SvStream& rInp)
847 ObjkType aObjk;
850 ReadObjkType( rInp, aObjk );
851 if(aObjk.Art==ObjGrup) {
852 GrupType aGrup;
853 ReadGrupType( rInp, aGrup );
854 rInp.Seek(rInp.Tell()+aGrup.Last); // object appendix
855 if(aGrup.GetSubPtr()!=0) SkipObjkList(rInp);
856 } else {
857 ObjkOverSeek(rInp,aObjk); // to next object
859 } while (aObjk.Next!=0 && !rInp.GetError());
862 bool SgfFilterSDrw( SvStream& rInp, SgfHeader&, SgfEntry&, GDIMetaFile& rMtf )
864 bool bRet = false;
865 PageType aPage;
866 ScopedVclPtrInstance< VirtualDevice > aOutDev;
867 OutputDevice* pOutDev;
868 sal_uLong nStdPos;
869 sal_uLong nCharPos;
870 sal_uInt16 Num;
872 pOutDev=aOutDev.get();
873 DtHdOverSeek(rInp); // read dataheader
875 nStdPos=rInp.Tell();
876 do { // read standard page
877 ReadPageType( rInp, aPage );
878 if (aPage.nList!=0) SkipObjkList(rInp);
879 } while (aPage.Next!=0 && !rInp.GetError());
881 nCharPos=rInp.Tell();
882 ReadPageType( rInp, aPage );
884 rMtf.Record(pOutDev);
885 Num=aPage.StdPg;
886 if (Num!=0) {
887 rInp.Seek(nStdPos);
888 while(Num>1 && aPage.Next!=0 && !rInp.GetError()) { // search standard page
889 ReadPageType( rInp, aPage );
890 if (aPage.nList!=0) SkipObjkList(rInp);
891 Num--;
893 ReadPageType( rInp, aPage );
894 if(Num==1 && aPage.nList!=0) DrawObjkList( rInp,*pOutDev );
895 rInp.Seek(nCharPos);
896 ReadPageType( rInp, aPage );
898 if (aPage.nList!=0) DrawObjkList(rInp,*pOutDev );
900 rMtf.Stop();
901 rMtf.WindStart();
902 MapMode aMap(MapUnit::Map10thMM,Point(),Fraction(1,4),Fraction(1,4));
903 rMtf.SetPrefMapMode(aMap);
904 rMtf.SetPrefSize(Size((sal_Int16)aPage.Paper.Size.x,(sal_Int16)aPage.Paper.Size.y));
905 bRet=true;
906 return bRet;
909 bool SgfSDrwFilter(SvStream& rInp, GDIMetaFile& rMtf, const INetURLObject& _aIniPath )
911 sal_uLong nFileStart; // offset of SgfHeaders. In general 0.
912 SgfHeader aHead;
913 SgfEntry aEntr;
914 sal_uLong nNext;
915 bool bRet=false; // return value
917 INetURLObject aIniPath = _aIniPath;
918 aIniPath.Append("sgf.ini");
920 pSgfFonts = new SgfFontLst;
922 pSgfFonts->AssignFN( aIniPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
923 nFileStart=rInp.Tell();
924 ReadSgfHeader( rInp, aHead );
925 if (aHead.ChkMagic() && aHead.Typ==SgfStarDraw && aHead.Version==SGV_VERSION) {
926 nNext=aHead.GetOffset();
927 while (nNext && !rInp.GetError()) {
928 rInp.Seek(nFileStart+nNext);
929 ReadSgfEntry( rInp, aEntr );
930 nNext=aEntr.GetOffset();
931 if (aEntr.Typ==aHead.Typ) {
932 bRet=SgfFilterSDrw( rInp,aHead,aEntr,rMtf );
934 } // while(nNext)
936 delete pSgfFonts;
937 return bRet;
940 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */