Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / source / filter / sgvmain.cxx
blobca754c28e4d9cb636abebde6f6e6c3b99ef8e416
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 #if defined OSL_BIGENDIAN
34 #define SWAPPOINT(p) { \
35 p.x=OSL_SWAPWORD(p.x); \
36 p.y=OSL_SWAPWORD(p.y); }
38 #define SWAPPAGE(p) { \
39 p.Next =OSL_SWAPDWORD (p.Next ); \
40 p.nList =OSL_SWAPDWORD (p.nList ); \
41 p.ListEnd=OSL_SWAPDWORD (p.ListEnd); \
42 p.Paper.Size.x=OSL_SWAPWORD(p.Paper.Size.x); \
43 p.Paper.Size.y=OSL_SWAPWORD(p.Paper.Size.y); \
44 p.Paper.RandL =OSL_SWAPWORD(p.Paper.RandL ); \
45 p.Paper.RandR =OSL_SWAPWORD(p.Paper.RandR ); \
46 p.Paper.RandO =OSL_SWAPWORD(p.Paper.RandO ); \
47 p.Paper.RandU =OSL_SWAPWORD(p.Paper.RandU ); \
48 SWAPPOINT(p.U); \
49 sal_uInt16 iTemp; \
50 for (iTemp=0;iTemp<20;iTemp++) { \
51 rPage.HlpLnH[iTemp]=OSL_SWAPWORD(rPage.HlpLnH[iTemp]); \
52 rPage.HlpLnV[iTemp]=OSL_SWAPWORD(rPage.HlpLnV[iTemp]); }}
54 #define SWAPOBJK(o) { \
55 o.Last =OSL_SWAPDWORD (o.Last ); \
56 o.Next =OSL_SWAPDWORD (o.Next ); \
57 o.MemSize =OSL_SWAPWORD(o.MemSize ); \
58 SWAPPOINT(o.ObjMin); \
59 SWAPPOINT(o.ObjMax); }
61 #define SWAPLINE(l) { \
62 l.LMSize=OSL_SWAPWORD(l.LMSize); \
63 l.LDicke=OSL_SWAPWORD(l.LDicke); }
65 #define SWAPAREA(a) { \
66 a.FDummy2=OSL_SWAPWORD(a.FDummy2); \
67 a.FMuster=OSL_SWAPWORD(a.FMuster); }
69 #define SWAPTEXT(t) { \
70 SWAPLINE(t.L); \
71 SWAPAREA(t.F); \
72 t.FontLo =OSL_SWAPWORD(t.FontLo ); \
73 t.FontHi =OSL_SWAPWORD(t.FontHi ); \
74 t.Grad =OSL_SWAPWORD(t.Grad ); \
75 t.Breite =OSL_SWAPWORD(t.Breite ); \
76 t.Schnitt=OSL_SWAPWORD(t.Schnitt); \
77 t.LnFeed =OSL_SWAPWORD(t.LnFeed ); \
78 t.Slant =OSL_SWAPWORD(t.Slant ); \
79 SWAPLINE(t.ShdL); \
80 SWAPAREA(t.ShdF); \
81 SWAPPOINT(t.ShdVers); \
82 SWAPAREA(t.BackF); }
84 #endif
86 // Restrictions:
88 // - area patterns are matched to the available ones in Starview.
89 // - line ends are always rounded in StarView and continue past the end of line.
90 // - line patterns are matched to the available ones in Starview.
91 // transparency/opacity is not taken into account
92 // - no rotated ellipses
94 // for font translation
95 SgfFontLst* pSgfFonts = 0;
97 // for circle kinds, text and rotated rectangles
98 void RotatePoint(PointType& P, sal_Int16 cx, sal_Int16 cy, double sn, double cs)
100 sal_Int16 dx,dy;
101 double x1,y1;
102 dx=P.x-cx;
103 dy=P.y-cy;
104 x1=dx*cs-dy*sn;
105 y1=dy*cs+dx*sn;
106 P.x=cx+sal_Int16(x1);
107 P.y=cy+sal_Int16(y1);
110 void RotatePoint(Point& P, sal_Int16 cx, sal_Int16 cy, double sn, double cs)
112 sal_Int16 dx,dy;
113 double x1,y1;
114 dx=(sal_Int16)(P.X()-cx);
115 dy=(sal_Int16)(P.Y()-cy);
116 x1=dx*cs-dy*sn;
117 y1=dy*cs+dx*sn;
118 P=Point(cx+sal_Int16(x1),cy+sal_Int16(y1));
121 sal_Int16 iMulDiv(sal_Int16 a, sal_Int16 Mul, sal_Int16 Div)
123 sal_Int32 Temp;
124 Temp=sal_Int32(a)*sal_Int32(Mul)/sal_Int32(Div);
125 return sal_Int16(Temp);
128 sal_uInt16 MulDiv(sal_uInt16 a, sal_uInt16 Mul, sal_uInt16 Div)
130 sal_uInt32 Temp;
131 Temp=sal_uInt32(a)*sal_uInt32(Mul)/sal_uInt32(Div);
132 return sal_uInt16(Temp);
135 // SgfFilterSDrw
137 SvStream& ReadDtHdType(SvStream& rIStream, DtHdType& rDtHd)
139 rIStream.Read(&rDtHd.Reserved[0], DtHdSize);
140 return rIStream;
143 void DtHdOverSeek(SvStream& rInp)
145 sal_uLong FPos=rInp.Tell();
146 FPos+=(sal_uLong)DtHdSize;
147 rInp.Seek(FPos);
150 PageType::PageType()
152 memset( this, 0, sizeof( PageType ) );
155 SvStream& ReadPageType(SvStream& rIStream, PageType& rPage)
157 rIStream.Read(&rPage.Next, PageSize);
158 #if defined OSL_BIGENDIAN
159 SWAPPAGE(rPage);
160 #endif
161 return rIStream;
164 void ObjkOverSeek(SvStream& rInp, ObjkType& rObjk)
166 sal_uLong Siz;
167 Siz=(sal_uLong)rObjk.MemSize+rObjk.Last; // ObjSize+ObjAnhSize
168 rInp.Seek(rInp.Tell()+Siz);
171 SvStream& ReadObjkType(SvStream& rInp, ObjkType& rObjk)
173 // fileposition in stream is not changed!
174 sal_uLong nPos;
175 nPos=rInp.Tell();
176 rInp.Read(&rObjk.Last, ObjkSize);
177 #if defined OSL_BIGENDIAN
178 SWAPOBJK(rObjk);
179 #endif
180 rInp.Seek(nPos);
181 return rInp;
183 SvStream& ReadStrkType(SvStream& rInp, StrkType& rStrk)
185 rInp.Read(&rStrk.Last, StrkSize);
186 #if defined OSL_BIGENDIAN
187 SWAPOBJK (rStrk);
188 SWAPLINE (rStrk.L);
189 SWAPPOINT(rStrk.Pos1);
190 SWAPPOINT(rStrk.Pos2);
191 #endif
192 return rInp;
194 SvStream& ReadRectType(SvStream& rInp, RectType& rRect)
196 rInp.Read(&rRect.Last, RectSize);
197 #if defined OSL_BIGENDIAN
198 SWAPOBJK (rRect);
199 SWAPLINE (rRect.L);
200 SWAPAREA (rRect.F);
201 SWAPPOINT(rRect.Pos1);
202 SWAPPOINT(rRect.Pos2);
203 rRect.Radius = OSL_SWAPWORD(rRect.Radius );
204 rRect.RotationAngle = OSL_SWAPWORD(rRect.RotationAngle);
205 rRect.Slant = OSL_SWAPWORD(rRect.Slant );
206 #endif
207 return rInp;
209 SvStream& ReadPolyType(SvStream& rInp, PolyType& rPoly)
211 rInp.Read(&rPoly.Last, PolySize);
212 #if defined OSL_BIGENDIAN
213 SWAPOBJK (rPoly);
214 SWAPLINE (rPoly.L);
215 SWAPAREA (rPoly.F);
216 #endif
217 return rInp;
219 SvStream& ReadSplnType(SvStream& rInp, SplnType& rSpln)
221 rInp.Read(&rSpln.Last, SplnSize);
222 #if defined OSL_BIGENDIAN
223 SWAPOBJK (rSpln);
224 SWAPLINE (rSpln.L);
225 SWAPAREA (rSpln.F);
226 #endif
227 return rInp;
229 SvStream& ReadCircType(SvStream& rInp, CircType& rCirc)
231 rInp.Read(&rCirc.Last, CircSize);
232 #if defined OSL_BIGENDIAN
233 SWAPOBJK (rCirc);
234 SWAPLINE (rCirc.L);
235 SWAPAREA (rCirc.F);
236 SWAPPOINT(rCirc.Radius);
237 SWAPPOINT(rCirc.Center);
238 rCirc.RotationAngle = OSL_SWAPWORD(rCirc.RotationAngle );
239 rCirc.StartAngle = OSL_SWAPWORD(rCirc.StartAngle);
240 rCirc.RelAngle = OSL_SWAPWORD(rCirc.RelAngle );
241 #endif
242 return rInp;
244 SvStream& ReadTextType(SvStream& rInp, TextType& rText)
246 rInp.Read(&rText.Last, TextSize);
247 #if defined OSL_BIGENDIAN
248 SWAPOBJK (rText);
249 SWAPTEXT (rText.T);
250 SWAPPOINT(rText.Pos1);
251 SWAPPOINT(rText.Pos2);
252 rText.TopOfs = OSL_SWAPWORD(rText.TopOfs );
253 rText.RotationAngle = OSL_SWAPWORD(rText.RotationAngle);
254 rText.BoxSlant = OSL_SWAPWORD(rText.BoxSlant);
255 rText.BufSize = OSL_SWAPWORD(rText.BufSize );
256 SWAPPOINT(rText.FitSize);
257 rText.FitBreit = OSL_SWAPWORD(rText.FitBreit);
258 #endif
259 rText.Buffer=NULL;
260 return rInp;
262 SvStream& ReadBmapType(SvStream& rInp, BmapType& rBmap)
264 rInp.Read(&rBmap.Last, BmapSize);
265 #if defined OSL_BIGENDIAN
266 SWAPOBJK (rBmap);
267 SWAPAREA (rBmap.F);
268 SWAPPOINT(rBmap.Pos1);
269 SWAPPOINT(rBmap.Pos2);
270 rBmap.RotationAngle = OSL_SWAPWORD(rBmap.RotationAngle);
271 rBmap.Slant = OSL_SWAPWORD(rBmap.Slant );
272 SWAPPOINT(rBmap.PixSize);
273 #endif
274 return rInp;
276 SvStream& ReadGrupType(SvStream& rInp, GrupType& rGrup)
278 rInp.Read(&rGrup.Last, GrupSize);
279 #if defined OSL_BIGENDIAN
280 SWAPOBJK (rGrup);
281 rGrup.SbLo =OSL_SWAPWORD(rGrup.SbLo );
282 rGrup.SbHi =OSL_SWAPWORD(rGrup.SbHi );
283 rGrup.UpLo =OSL_SWAPWORD(rGrup.UpLo );
284 rGrup.UpHi =OSL_SWAPWORD(rGrup.UpHi );
285 rGrup.ChartSize=OSL_SWAPWORD(rGrup.ChartSize);
286 rGrup.ChartPtr =OSL_SWAPDWORD (rGrup.ChartPtr );
287 #endif
288 return rInp;
291 Color Sgv2SvFarbe(sal_uInt8 nFrb1, sal_uInt8 nFrb2, sal_uInt8 nInts)
293 sal_uInt16 r1=0,g1=0,b1=0,r2=0,g2=0,b2=0;
294 sal_uInt8 nInt2=100-nInts;
295 switch(nFrb1 & 0x07) {
296 case 0: r1=0xFF; g1=0xFF; b1=0xFF; break;
297 case 1: r1=0xFF; g1=0xFF; break;
298 case 2: g1=0xFF; b1=0xFF; break;
299 case 3: g1=0xFF; break;
300 case 4: r1=0xFF; b1=0xFF; break;
301 case 5: r1=0xFF; break;
302 case 6: b1=0xFF; break;
303 case 7: break;
305 switch(nFrb2 & 0x07) {
306 case 0: r2=0xFF; g2=0xFF; b2=0xFF; break;
307 case 1: r2=0xFF; g2=0xFF; break;
308 case 2: g2=0xFF; b2=0xFF; break;
309 case 3: g2=0xFF; break;
310 case 4: r2=0xFF; b2=0xFF; break;
311 case 5: r2=0xFF; break;
312 case 6: b2=0xFF; break;
313 case 7: break;
315 r1=(sal_uInt16)((sal_uInt32)r1*nInts/100+(sal_uInt32)r2*nInt2/100);
316 g1=(sal_uInt16)((sal_uInt32)g1*nInts/100+(sal_uInt32)g2*nInt2/100);
317 b1=(sal_uInt16)((sal_uInt32)b1*nInts/100+(sal_uInt32)b2*nInt2/100);
318 Color aColor( (sal_uInt8)r1, (sal_uInt8)g1, (sal_uInt8)b1 );
319 return aColor;
322 void SetLine(ObjLineType& rLine, OutputDevice& rOut)
324 if( 0 == ( rLine.LMuster & 0x07 ) )
325 rOut.SetLineColor();
326 else
327 rOut.SetLineColor( Sgv2SvFarbe(rLine.LFarbe,rLine.LBFarbe,rLine.LIntens) );
330 void SetArea(ObjAreaType& rArea, OutputDevice& rOut)
332 if( 0 == ( rArea.FMuster & 0x00FF ) )
333 rOut.SetFillColor();
334 else
335 rOut.SetFillColor( Sgv2SvFarbe( rArea.FFarbe,rArea.FBFarbe,rArea.FIntens ) );
338 void ObjkType::Draw(OutputDevice&)
342 void Obj0Type::Draw(OutputDevice&) {}
344 void StrkType::Draw(OutputDevice& rOut)
346 SetLine(L,rOut);
347 rOut.DrawLine(Point(Pos1.x,Pos1.y),Point(Pos2.x,Pos2.y)); // !!!
350 void SgfAreaColorIntens(sal_uInt16 Muster, sal_uInt8 Col1, sal_uInt8 Col2, sal_uInt8 Int, OutputDevice& rOut)
352 ObjAreaType F;
353 F.FMuster=Muster;
354 F.FFarbe=Col2;
355 F.FBFarbe=Col1;
356 F.FIntens=Int;
357 SetArea(F,rOut);
360 void DrawSlideRect(sal_Int16 x1, sal_Int16 y1, sal_Int16 x2, sal_Int16 y2, ObjAreaType& F, OutputDevice& rOut)
362 sal_Int16 i,i0,b,b0;
363 sal_Int16 Int1,Int2;
364 sal_Int16 Col1,Col2;
365 // ClipMerk: HgdClipRec;
366 sal_Int16 cx,cy;
367 sal_Int16 MaxR;
368 sal_Int32 dx,dy;
370 rOut.SetLineColor();
371 if (x1>x2) { i=x1; x1=x2; x2=i; }
372 if (y1>y2) { i=y1; y1=y2; y2=i; }
373 Col1=F.FBFarbe & 0x87; Col2=F.FFarbe & 0x87;
374 Int1=100-F.FIntens; Int2=F.FIntens;
375 if (Int1==Int2) {
376 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
377 rOut.DrawRect(Rectangle(x1,y1,x2,y2));
378 } else {
379 b0=Int1;
380 switch (F.FBFarbe & 0x38) {
381 case 0x08: { // vertikal
382 i0=y1;
383 i=y1;
384 while (i<=y2) {
385 b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-y1) /(sal_Int32)(y2-y1+1));
386 if (b!=b0) {
387 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
388 rOut.DrawRect(Rectangle(x1,i0,x2,i-1));
389 i0=i; b0=b;
391 i++;
393 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
394 rOut.DrawRect(Rectangle(x1,i0,x2,y2));
395 } break;
396 case 0x28: { // horizontal
397 i0=x1;
398 i=x1;
399 while (i<=x2) {
400 b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-x1) /(sal_Int32)(x2-x1+1));
401 if (b!=b0) {
402 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
403 rOut.DrawRect(Rectangle(i0,y1,i-1,y2));
404 i0=i; b0=b;
406 i++;
408 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
409 rOut.DrawRect(Rectangle(i0,y1,x2,y2));
410 } break;
412 case 0x18: case 0x38: { // circle
413 vcl::Region ClipMerk=rOut.GetClipRegion();
414 double a;
416 rOut.SetClipRegion(vcl::Region(Rectangle(x1,y1,x2,y2)));
417 cx=(x1+x2) /2;
418 cy=(y1+y2) /2;
419 dx=x2-x1+1;
420 dy=y2-y1+1;
421 a=sqrt((double)(dx*dx+dy*dy));
422 MaxR=sal_Int16(a) /2 +1;
423 b0=Int2;
424 i0=MaxR; if (MaxR<1) MaxR=1;
425 i=MaxR;
426 while (i>=0) {
427 b=Int1+sal_Int16((sal_Int32(Int2-Int1)*sal_Int32(i)) /sal_Int32(MaxR));
428 if (b!=b0) {
429 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
430 rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
431 i0=i; b0=b;
433 i--;
435 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int1,rOut);
436 rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
437 rOut.SetClipRegion(ClipMerk);
438 } break; // circle
443 void RectType::Draw(OutputDevice& rOut)
445 if (L.LMuster!=0) L.LMuster=1; // no line separator here, only on or off
446 SetArea(F,rOut);
447 if (RotationAngle==0) {
448 if ((F.FBFarbe & 0x38)==0 || Radius!=0) {
449 SetLine(L,rOut);
450 rOut.DrawRect(Rectangle(Pos1.x,Pos1.y,Pos2.x,Pos2.y),Radius,Radius);
451 } else {
452 DrawSlideRect(Pos1.x,Pos1.y,Pos2.x,Pos2.y,F,rOut);
453 if (L.LMuster!=0) {
454 SetLine(L,rOut);
455 rOut.SetFillColor();
456 rOut.DrawRect(Rectangle(Pos1.x,Pos1.y,Pos2.x,Pos2.y));
459 } else {
460 Point aPts[4];
461 sal_uInt16 i;
462 double sn,cs;
463 sn=sin(double(RotationAngle)*3.14159265359/18000);
464 cs=cos(double(RotationAngle)*3.14159265359/18000);
465 aPts[0]=Point(Pos1.x,Pos1.y);
466 aPts[1]=Point(Pos2.x,Pos1.y);
467 aPts[2]=Point(Pos2.x,Pos2.y);
468 aPts[3]=Point(Pos1.x,Pos2.y);
469 for (i=0;i<4;i++) {
470 RotatePoint(aPts[i],Pos1.x,Pos1.y,sn,cs);
472 SetLine(L,rOut);
473 Polygon aPoly(4,aPts);
474 rOut.DrawPolygon(aPoly);
478 void PolyType::Draw(OutputDevice& rOut)
480 if ((Flags & PolyClosBit) !=0) SetArea(F,rOut);
481 SetLine(L,rOut);
482 Polygon aPoly(nPoints);
483 sal_uInt16 i;
484 for(i=0;i<nPoints;i++) aPoly.SetPoint(Point(EckP[i].x,EckP[i].y),i);
485 if ((Flags & PolyClosBit) !=0) {
486 rOut.DrawPolygon(aPoly);
487 } else {
488 rOut.DrawPolyLine(aPoly);
492 void SplnType::Draw(OutputDevice& rOut)
494 if ((Flags & PolyClosBit) !=0) SetArea(F,rOut);
495 SetLine(L,rOut);
496 Polygon aPoly(0);
497 Polygon aSpln(nPoints);
498 sal_uInt16 i;
499 for(i=0;i<nPoints;i++) aSpln.SetPoint(Point(EckP[i].x,EckP[i].y),i);
500 if ((Flags & PolyClosBit) !=0) {
501 Spline2Poly(aSpln,true,aPoly);
502 if (aPoly.GetSize()>0) rOut.DrawPolygon(aPoly);
503 } else {
504 Spline2Poly(aSpln,false,aPoly);
505 if (aPoly.GetSize()>0) rOut.DrawPolyLine(aPoly);
509 void DrawSlideCirc(sal_Int16 cx, sal_Int16 cy, sal_Int16 rx, sal_Int16 ry, ObjAreaType& F, OutputDevice& rOut)
511 sal_Int16 x1=cx-rx;
512 sal_Int16 y1=cy-ry;
513 sal_Int16 x2=cx+rx;
514 sal_Int16 y2=cy+ry;
516 sal_Int16 i,i0,b,b0;
517 sal_Int16 Int1,Int2;
518 sal_Int16 Col1,Col2;
520 rOut.SetLineColor();
521 Col1=F.FBFarbe & 0x87; Col2=F.FFarbe & 0x87;
522 Int1=100-F.FIntens; Int2=F.FIntens;
523 if (Int1==Int2) {
524 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
525 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
526 } else {
527 b0=Int1;
528 switch (F.FBFarbe & 0x38) {
529 case 0x08: { // vertical
530 vcl::Region ClipMerk=rOut.GetClipRegion();
531 i0=y1;
532 i=y1;
533 while (i<=y2) {
534 b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-y1) /(sal_Int32)(y2-y1+1));
535 if (b!=b0) {
536 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
537 rOut.SetClipRegion(vcl::Region(Rectangle(x1,i0,x2,i-1)));
538 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
539 i0=i; b0=b;
541 i++;
543 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
544 rOut.SetClipRegion(vcl::Region(Rectangle(x1,i0,x2,y2)));
545 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
546 rOut.SetClipRegion(ClipMerk);
547 } break;
548 case 0x28: { // horizontal
549 vcl::Region ClipMerk=rOut.GetClipRegion();
550 i0=x1;
551 i=x1;
552 while (i<=x2) {
553 b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-x1) /(sal_Int32)(x2-x1+1));
554 if (b!=b0) {
555 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
556 rOut.SetClipRegion(vcl::Region(Rectangle(i0,y1,i-1,y2)));
557 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
558 i0=i; b0=b;
560 i++;
562 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
563 rOut.SetClipRegion(vcl::Region(Rectangle(i0,y1,x2,y2)));
564 rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
565 rOut.SetClipRegion(ClipMerk);
566 } break;
568 case 0x18: case 0x38: { // circle
569 sal_Int16 MaxR;
571 if (rx<1) rx=1;
572 if (ry<1) ry=1;
573 MaxR=rx;
574 b0=Int2;
575 i0=MaxR;
576 i=MaxR;
577 while (i>=0) {
578 b=Int1+sal_Int16((sal_Int32(Int2-Int1)*sal_Int32(i)) /sal_Int32(MaxR));
579 if (b!=b0) {
580 sal_Int32 temp=sal_Int32(i0)*sal_Int32(ry)/sal_Int32(rx);
581 sal_Int16 j0=sal_Int16(temp);
582 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
583 rOut.DrawEllipse(Rectangle(cx-i0,cy-j0,cx+i0,cy+j0));
584 i0=i; b0=b;
586 i--;
588 SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int1,rOut);
589 rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
590 } break; // circle
595 void CircType::Draw(OutputDevice& rOut)
597 Rectangle aRect(Center.x-Radius.x,Center.y-Radius.y,Center.x+Radius.x,Center.y+Radius.y);
599 if (L.LMuster!=0) L.LMuster=1; // no line pattern here, only on or off
600 SetArea(F,rOut);
601 if ((Flags & 0x03)==CircFull) {
602 if ((F.FBFarbe & 0x38)==0) {
603 SetLine(L,rOut);
604 rOut.DrawEllipse(aRect);
605 } else {
606 DrawSlideCirc(Center.x,Center.y,Radius.x,Radius.y,F,rOut);
607 if (L.LMuster!=0) {
608 SetLine(L,rOut);
609 rOut.SetFillColor();
610 rOut.DrawEllipse(aRect);
613 } else {
614 PointType a,b;
615 Point aStrt,aEnde;
616 double sn,cs;
618 a.x=Center.x+Radius.x; a.y=Center.y; b=a;
619 sn=sin(double(StartAngle)*3.14159265359/18000);
620 cs=cos(double(StartAngle)*3.14159265359/18000);
621 RotatePoint(a,Center.x,Center.y,sn,cs);
622 sn=sin(double(StartAngle+RelAngle)*3.14159265359/18000);
623 cs=cos(double(StartAngle+RelAngle)*3.14159265359/18000);
624 RotatePoint(b,Center.x,Center.y,sn,cs);
625 if (Radius.x!=Radius.y) {
626 if (Radius.x<1) Radius.x=1;
627 if (Radius.y<1) Radius.y=1;
628 a.y = a.y - Center.y;
629 b.y = b.y - Center.y;
630 a.y=iMulDiv(a.y,Radius.y,Radius.x);
631 b.y=iMulDiv(b.y,Radius.y,Radius.x);
632 a.y = a.y + Center.y;
633 b.y = b.y + Center.y;
635 aStrt=Point(a.x,a.y);
636 aEnde=Point(b.x,b.y);
637 SetLine(L,rOut);
638 switch (Flags & 0x03) {
639 case CircArc : rOut.DrawArc(aRect,aEnde,aStrt); break;
640 case CircSect:
641 case CircAbsn: rOut.DrawPie(aRect,aEnde,aStrt); break;
646 void BmapType::Draw(OutputDevice& rOut)
648 //ifstream aInp;
649 unsigned char nSgfTyp;
650 sal_uInt16 nVersion;
651 OUString aStr(
652 reinterpret_cast< char const * >(&Filename[ 1 ]),
653 (sal_Int32)Filename[ 0 ], RTL_TEXTENCODING_UTF8 );
654 INetURLObject aFNam( aStr );
656 SvStream* pInp = ::utl::UcbStreamHelper::CreateStream( aFNam.GetMainURL( INetURLObject::NO_DECODE ), StreamMode::READ );
657 if ( pInp )
659 nSgfTyp=CheckSgfTyp( *pInp,nVersion);
660 switch(nSgfTyp) {
661 case SGF_BITIMAGE: {
662 GraphicFilter aFlt;
663 Graphic aGrf;
664 aFlt.ImportGraphic(aGrf,aFNam);
665 aGrf.Draw(&rOut,Point(Pos1.x,Pos1.y),Size(Pos2.x-Pos1.x,Pos2.y-Pos1.y));
666 } break;
667 case SGF_SIMPVECT: {
668 GDIMetaFile aMtf;
669 SgfVectXofs=Pos1.x;
670 SgfVectYofs=Pos1.y;
671 SgfVectXmul=Pos2.x-Pos1.x;
672 SgfVectYmul=Pos2.y-Pos1.y;
673 SgfVectXdiv=0;
674 SgfVectYdiv=0;
675 SgfVectScal=true;
676 SgfVectFilter(*pInp,aMtf);
677 SgfVectXofs=0;
678 SgfVectYofs=0;
679 SgfVectXmul=0;
680 SgfVectYmul=0;
681 SgfVectXdiv=0;
682 SgfVectYdiv=0;
683 SgfVectScal=false;
684 aMtf.Play(&rOut);
685 } break;
687 delete pInp;
691 sal_uInt32 GrupType::GetSubPtr()
693 return sal_uInt32(SbLo)+0x00010000*sal_uInt32(SbHi);
696 void DrawObjkList( SvStream& rInp, OutputDevice& rOut )
698 ObjkType aObjk;
699 sal_uInt16 nGrpCnt=0;
700 bool bEnd=false;
701 do {
702 ReadObjkType( rInp, aObjk );
703 if (!rInp.GetError()) {
704 switch(aObjk.Art) {
705 case ObjStrk: { StrkType aStrk; ReadStrkType( rInp, aStrk ); if (!rInp.GetError()) aStrk.Draw(rOut); } break;
706 case ObjRect: { RectType aRect; ReadRectType( rInp, aRect ); if (!rInp.GetError()) aRect.Draw(rOut); } break;
707 case ObjCirc: { CircType aCirc; ReadCircType( rInp, aCirc ); if (!rInp.GetError()) aCirc.Draw(rOut); } break;
708 case ObjText: {
709 TextType aText;
710 ReadTextType( rInp, aText );
711 if (!rInp.GetError()) {
712 aText.Buffer=new UCHAR[aText.BufSize+1]; // add one for LookAhead at CK-separation
713 rInp.Read(aText.Buffer, aText.BufSize);
714 if (!rInp.GetError()) aText.Draw(rOut);
715 delete[] aText.Buffer;
717 } break;
718 case ObjBmap: {
719 BmapType aBmap;
720 ReadBmapType( rInp, aBmap );
721 if (!rInp.GetError()) {
722 aBmap.Draw(rOut);
724 } break;
725 case ObjPoly: {
726 PolyType aPoly;
727 ReadPolyType( rInp, aPoly );
728 if (!rInp.GetError()) {
729 aPoly.EckP=new PointType[aPoly.nPoints];
730 rInp.Read(aPoly.EckP, 4*aPoly.nPoints);
731 #if defined OSL_BIGENDIAN
732 for(short i=0;i<aPoly.nPoints;i++) SWAPPOINT(aPoly.EckP[i]);
733 #endif
734 if (!rInp.GetError()) aPoly.Draw(rOut);
735 delete[] aPoly.EckP;
737 } break;
738 case ObjSpln: {
739 SplnType aSpln;
740 ReadSplnType( rInp, aSpln );
741 if (!rInp.GetError()) {
742 aSpln.EckP=new PointType[aSpln.nPoints];
743 rInp.Read(aSpln.EckP, 4*aSpln.nPoints);
744 #if defined OSL_BIGENDIAN
745 for(short i=0;i<aSpln.nPoints;i++) SWAPPOINT(aSpln.EckP[i]);
746 #endif
747 if (!rInp.GetError()) aSpln.Draw(rOut);
748 delete[] aSpln.EckP;
750 } break;
751 case ObjGrup: {
752 GrupType aGrup;
753 ReadGrupType( rInp, aGrup );
754 if (!rInp.GetError()) {
755 rInp.Seek(rInp.Tell()+aGrup.Last); // object appendix
756 if(aGrup.GetSubPtr()!=0L) nGrpCnt++; // DrawObjkList(rInp,rOut );
758 } break;
759 default: {
760 aObjk.Draw(rOut); // object name on 2. Screen
761 ObjkOverSeek(rInp,aObjk); // to next object
764 } // if rInp
765 if (!rInp.GetError()) {
766 if (aObjk.Next==0L) {
767 if (nGrpCnt==0) bEnd=true;
768 else nGrpCnt--;
770 } else {
771 bEnd=true; // read error
773 } while (!bEnd);
776 void SkipObjkList(SvStream& rInp)
778 ObjkType aObjk;
781 ReadObjkType( rInp, aObjk );
782 if(aObjk.Art==ObjGrup) {
783 GrupType aGrup;
784 ReadGrupType( rInp, aGrup );
785 rInp.Seek(rInp.Tell()+aGrup.Last); // object appendix
786 if(aGrup.GetSubPtr()!=0L) SkipObjkList(rInp);
787 } else {
788 ObjkOverSeek(rInp,aObjk); // to next object
790 } while (aObjk.Next!=0L && !rInp.GetError());
793 bool SgfFilterSDrw( SvStream& rInp, SgfHeader&, SgfEntry&, GDIMetaFile& rMtf )
795 bool bRet = false;
796 PageType aPage;
797 ScopedVclPtrInstance< VirtualDevice > aOutDev;
798 OutputDevice* pOutDev;
799 sal_uLong nStdPos;
800 sal_uLong nCharPos;
801 sal_uInt16 Num;
803 pOutDev=aOutDev.get();
804 DtHdOverSeek(rInp); // read dataheader
806 nStdPos=rInp.Tell();
807 do { // read standard page
808 ReadPageType( rInp, aPage );
809 if (aPage.nList!=0) SkipObjkList(rInp);
810 } while (aPage.Next!=0L && !rInp.GetError());
812 nCharPos=rInp.Tell();
813 ReadPageType( rInp, aPage );
815 rMtf.Record(pOutDev);
816 Num=aPage.StdPg;
817 if (Num!=0) {
818 rInp.Seek(nStdPos);
819 while(Num>1 && aPage.Next!=0L && !rInp.GetError()) { // search standard page
820 ReadPageType( rInp, aPage );
821 if (aPage.nList!=0) SkipObjkList(rInp);
822 Num--;
824 ReadPageType( rInp, aPage );
825 if(Num==1 && aPage.nList!=0L) DrawObjkList( rInp,*pOutDev );
826 rInp.Seek(nCharPos);
827 nCharPos=rInp.Tell();
828 ReadPageType( rInp, aPage );
830 if (aPage.nList!=0L) DrawObjkList(rInp,*pOutDev );
832 rMtf.Stop();
833 rMtf.WindStart();
834 MapMode aMap(MAP_10TH_MM,Point(),Fraction(1,4),Fraction(1,4));
835 rMtf.SetPrefMapMode(aMap);
836 rMtf.SetPrefSize(Size((sal_Int16)aPage.Paper.Size.x,(sal_Int16)aPage.Paper.Size.y));
837 bRet=true;
838 return bRet;
841 bool SgfSDrwFilter(SvStream& rInp, GDIMetaFile& rMtf, const INetURLObject& _aIniPath )
843 #if OSL_DEBUG_LEVEL > 1 // check record size. New compiler possibly aligns different!
844 if (sizeof(ObjTextType)!=ObjTextTypeSize) return false;
845 #endif
847 sal_uLong nFileStart; // offset of SgfHeaders. In general 0.
848 SgfHeader aHead;
849 SgfEntry aEntr;
850 sal_uLong nNext;
851 bool bRet=false; // return value
853 INetURLObject aIniPath = _aIniPath;
854 aIniPath.Append(OUString("sgf.ini"));
856 pSgfFonts = new SgfFontLst;
858 pSgfFonts->AssignFN( aIniPath.GetMainURL( INetURLObject::NO_DECODE ) );
859 nFileStart=rInp.Tell();
860 ReadSgfHeader( rInp, aHead );
861 if (aHead.ChkMagic() && aHead.Typ==SgfStarDraw && aHead.Version==SGV_VERSION) {
862 nNext=aHead.GetOffset();
863 while (nNext && !rInp.GetError()) {
864 rInp.Seek(nFileStart+nNext);
865 ReadSgfEntry( rInp, aEntr );
866 nNext=aEntr.GetOffset();
867 if (aEntr.Typ==aHead.Typ) {
868 bRet=SgfFilterSDrw( rInp,aHead,aEntr,rMtf );
870 } // while(nNext)
872 delete pSgfFonts;
873 return bRet;
876 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */