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 <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>
31 :
32 : #if defined OSL_BIGENDIAN
33 :
34 : #define SWAPPOINT(p) { \
35 : p.x=OSL_SWAPWORD(p.x); \
36 : p.y=OSL_SWAPWORD(p.y); }
37 :
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]); }}
53 :
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); }
60 :
61 : #define SWAPLINE(l) { \
62 : l.LMSize=OSL_SWAPWORD(l.LMSize); \
63 : l.LDicke=OSL_SWAPWORD(l.LDicke); }
64 :
65 : #define SWAPAREA(a) { \
66 : a.FDummy2=OSL_SWAPWORD(a.FDummy2); \
67 : a.FMuster=OSL_SWAPWORD(a.FMuster); }
68 :
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); }
83 :
84 : #endif
85 :
86 : // Restrictions:
87 :
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
93 :
94 : // for font translation
95 : SgfFontLst* pSgfFonts = 0;
96 :
97 : // for circle kinds, text and rotated rectangles
98 0 : void RotatePoint(PointType& P, sal_Int16 cx, sal_Int16 cy, double sn, double cs)
99 : {
100 : sal_Int16 dx,dy;
101 : double x1,y1;
102 0 : dx=P.x-cx;
103 0 : dy=P.y-cy;
104 0 : x1=dx*cs-dy*sn;
105 0 : y1=dy*cs+dx*sn;
106 0 : P.x=cx+sal_Int16(x1);
107 0 : P.y=cy+sal_Int16(y1);
108 0 : }
109 :
110 0 : void RotatePoint(Point& P, sal_Int16 cx, sal_Int16 cy, double sn, double cs)
111 : {
112 : sal_Int16 dx,dy;
113 : double x1,y1;
114 0 : dx=(sal_Int16)(P.X()-cx);
115 0 : dy=(sal_Int16)(P.Y()-cy);
116 0 : x1=dx*cs-dy*sn;
117 0 : y1=dy*cs+dx*sn;
118 0 : P=Point(cx+sal_Int16(x1),cy+sal_Int16(y1));
119 0 : }
120 :
121 0 : sal_Int16 iMulDiv(sal_Int16 a, sal_Int16 Mul, sal_Int16 Div)
122 : {
123 : sal_Int32 Temp;
124 0 : Temp=sal_Int32(a)*sal_Int32(Mul)/sal_Int32(Div);
125 0 : return sal_Int16(Temp);
126 : }
127 :
128 0 : sal_uInt16 MulDiv(sal_uInt16 a, sal_uInt16 Mul, sal_uInt16 Div)
129 : {
130 : sal_uInt32 Temp;
131 0 : Temp=sal_uInt32(a)*sal_uInt32(Mul)/sal_uInt32(Div);
132 0 : return sal_uInt16(Temp);
133 : }
134 :
135 : // SgfFilterSDrw
136 :
137 0 : SvStream& ReadDtHdType(SvStream& rIStream, DtHdType& rDtHd)
138 : {
139 0 : rIStream.Read(&rDtHd.Reserved[0], DtHdSize);
140 0 : return rIStream;
141 : }
142 :
143 2 : void DtHdOverSeek(SvStream& rInp)
144 : {
145 2 : sal_uLong FPos=rInp.Tell();
146 2 : FPos+=(sal_uLong)DtHdSize;
147 2 : rInp.Seek(FPos);
148 2 : }
149 :
150 2 : PageType::PageType()
151 : {
152 2 : memset( this, 0, sizeof( PageType ) );
153 2 : }
154 :
155 8 : SvStream& ReadPageType(SvStream& rIStream, PageType& rPage)
156 : {
157 8 : rIStream.Read(&rPage.Next, PageSize);
158 : #if defined OSL_BIGENDIAN
159 : SWAPPAGE(rPage);
160 : #endif
161 8 : return rIStream;
162 : }
163 :
164 0 : void ObjkOverSeek(SvStream& rInp, ObjkType& rObjk)
165 : {
166 : sal_uLong Siz;
167 0 : Siz=(sal_uLong)rObjk.MemSize+rObjk.Last; // ObjSize+ObjAnhSize
168 0 : rInp.Seek(rInp.Tell()+Siz);
169 0 : }
170 :
171 8 : SvStream& ReadObjkType(SvStream& rInp, ObjkType& rObjk)
172 : {
173 : // fileposition in stream is not changed!
174 : sal_uLong nPos;
175 8 : nPos=rInp.Tell();
176 8 : rInp.Read(&rObjk.Last, ObjkSize);
177 : #if defined OSL_BIGENDIAN
178 : SWAPOBJK(rObjk);
179 : #endif
180 8 : rInp.Seek(nPos);
181 8 : return rInp;
182 : }
183 0 : SvStream& ReadStrkType(SvStream& rInp, StrkType& rStrk)
184 : {
185 0 : 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 0 : return rInp;
193 : }
194 0 : SvStream& ReadRectType(SvStream& rInp, RectType& rRect)
195 : {
196 0 : 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 0 : return rInp;
208 : }
209 3 : SvStream& ReadPolyType(SvStream& rInp, PolyType& rPoly)
210 : {
211 3 : rInp.Read(&rPoly.Last, PolySize);
212 : #if defined OSL_BIGENDIAN
213 : SWAPOBJK (rPoly);
214 : SWAPLINE (rPoly.L);
215 : SWAPAREA (rPoly.F);
216 : #endif
217 3 : return rInp;
218 : }
219 3 : SvStream& ReadSplnType(SvStream& rInp, SplnType& rSpln)
220 : {
221 3 : rInp.Read(&rSpln.Last, SplnSize);
222 : #if defined OSL_BIGENDIAN
223 : SWAPOBJK (rSpln);
224 : SWAPLINE (rSpln.L);
225 : SWAPAREA (rSpln.F);
226 : #endif
227 3 : return rInp;
228 : }
229 1 : SvStream& ReadCircType(SvStream& rInp, CircType& rCirc)
230 : {
231 1 : 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 1 : return rInp;
243 : }
244 0 : SvStream& ReadTextType(SvStream& rInp, TextType& rText)
245 : {
246 0 : 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 0 : rText.Buffer=NULL;
260 0 : return rInp;
261 : }
262 0 : SvStream& ReadBmapType(SvStream& rInp, BmapType& rBmap)
263 : {
264 0 : 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 0 : return rInp;
275 : }
276 1 : SvStream& ReadGrupType(SvStream& rInp, GrupType& rGrup)
277 : {
278 1 : 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 1 : return rInp;
289 : }
290 :
291 12 : Color Sgv2SvFarbe(sal_uInt8 nFrb1, sal_uInt8 nFrb2, sal_uInt8 nInts)
292 : {
293 12 : sal_uInt16 r1=0,g1=0,b1=0,r2=0,g2=0,b2=0;
294 12 : sal_uInt8 nInt2=100-nInts;
295 12 : switch(nFrb1 & 0x07) {
296 1 : case 0: r1=0xFF; g1=0xFF; b1=0xFF; break;
297 0 : case 1: r1=0xFF; g1=0xFF; break;
298 0 : case 2: g1=0xFF; b1=0xFF; break;
299 1 : case 3: g1=0xFF; break;
300 1 : case 4: r1=0xFF; b1=0xFF; break;
301 0 : case 5: r1=0xFF; break;
302 1 : case 6: b1=0xFF; break;
303 8 : case 7: break;
304 : }
305 12 : switch(nFrb2 & 0x07) {
306 12 : case 0: r2=0xFF; g2=0xFF; b2=0xFF; break;
307 0 : case 1: r2=0xFF; g2=0xFF; break;
308 0 : case 2: g2=0xFF; b2=0xFF; break;
309 0 : case 3: g2=0xFF; break;
310 0 : case 4: r2=0xFF; b2=0xFF; break;
311 0 : case 5: r2=0xFF; break;
312 0 : case 6: b2=0xFF; break;
313 0 : case 7: break;
314 : }
315 12 : r1=(sal_uInt16)((sal_uInt32)r1*nInts/100+(sal_uInt32)r2*nInt2/100);
316 12 : g1=(sal_uInt16)((sal_uInt32)g1*nInts/100+(sal_uInt32)g2*nInt2/100);
317 12 : b1=(sal_uInt16)((sal_uInt32)b1*nInts/100+(sal_uInt32)b2*nInt2/100);
318 12 : Color aColor( (sal_uInt8)r1, (sal_uInt8)g1, (sal_uInt8)b1 );
319 12 : return aColor;
320 : }
321 :
322 7 : void SetLine(ObjLineType& rLine, OutputDevice& rOut)
323 : {
324 7 : if( 0 == ( rLine.LMuster & 0x07 ) )
325 0 : rOut.SetLineColor();
326 : else
327 7 : rOut.SetLineColor( Sgv2SvFarbe(rLine.LFarbe,rLine.LBFarbe,rLine.LIntens) );
328 7 : }
329 :
330 7 : void SetArea(ObjAreaType& rArea, OutputDevice& rOut)
331 : {
332 7 : if( 0 == ( rArea.FMuster & 0x00FF ) )
333 2 : rOut.SetFillColor();
334 : else
335 5 : rOut.SetFillColor( Sgv2SvFarbe( rArea.FFarbe,rArea.FBFarbe,rArea.FIntens ) );
336 7 : }
337 :
338 0 : void ObjkType::Draw(OutputDevice&)
339 : {
340 0 : }
341 :
342 0 : void Obj0Type::Draw(OutputDevice&) {}
343 :
344 0 : void StrkType::Draw(OutputDevice& rOut)
345 : {
346 0 : SetLine(L,rOut);
347 0 : rOut.DrawLine(Point(Pos1.x,Pos1.y),Point(Pos2.x,Pos2.y)); // !!!
348 0 : }
349 :
350 0 : void SgfAreaColorIntens(sal_uInt16 Muster, sal_uInt8 Col1, sal_uInt8 Col2, sal_uInt8 Int, OutputDevice& rOut)
351 : {
352 0 : ObjAreaType F;
353 0 : F.FMuster=Muster;
354 0 : F.FFarbe=Col2;
355 0 : F.FBFarbe=Col1;
356 0 : F.FIntens=Int;
357 0 : SetArea(F,rOut);
358 0 : }
359 :
360 0 : void DrawSlideRect(sal_Int16 x1, sal_Int16 y1, sal_Int16 x2, sal_Int16 y2, ObjAreaType& F, OutputDevice& rOut)
361 : {
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;
369 :
370 0 : rOut.SetLineColor();
371 0 : if (x1>x2) { i=x1; x1=x2; x2=i; }
372 0 : if (y1>y2) { i=y1; y1=y2; y2=i; }
373 0 : Col1=F.FBFarbe & 0x87; Col2=F.FFarbe & 0x87;
374 0 : Int1=100-F.FIntens; Int2=F.FIntens;
375 0 : if (Int1==Int2) {
376 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
377 0 : rOut.DrawRect(Rectangle(x1,y1,x2,y2));
378 : } else {
379 0 : b0=Int1;
380 0 : switch (F.FBFarbe & 0x38) {
381 : case 0x08: { // vertikal
382 0 : i0=y1;
383 0 : i=y1;
384 0 : while (i<=y2) {
385 0 : b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-y1) /(sal_Int32)(y2-y1+1));
386 0 : if (b!=b0) {
387 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
388 0 : rOut.DrawRect(Rectangle(x1,i0,x2,i-1));
389 0 : i0=i; b0=b;
390 : }
391 0 : i++;
392 : }
393 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
394 0 : rOut.DrawRect(Rectangle(x1,i0,x2,y2));
395 0 : } break;
396 : case 0x28: { // horizontal
397 0 : i0=x1;
398 0 : i=x1;
399 0 : while (i<=x2) {
400 0 : b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-x1) /(sal_Int32)(x2-x1+1));
401 0 : if (b!=b0) {
402 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
403 0 : rOut.DrawRect(Rectangle(i0,y1,i-1,y2));
404 0 : i0=i; b0=b;
405 : }
406 0 : i++;
407 : }
408 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
409 0 : rOut.DrawRect(Rectangle(i0,y1,x2,y2));
410 0 : } break;
411 :
412 : case 0x18: case 0x38: { // circle
413 0 : vcl::Region ClipMerk=rOut.GetClipRegion();
414 : double a;
415 :
416 0 : rOut.SetClipRegion(vcl::Region(Rectangle(x1,y1,x2,y2)));
417 0 : cx=(x1+x2) /2;
418 0 : cy=(y1+y2) /2;
419 0 : dx=x2-x1+1;
420 0 : dy=y2-y1+1;
421 0 : a=sqrt((double)(dx*dx+dy*dy));
422 0 : MaxR=sal_Int16(a) /2 +1;
423 0 : b0=Int2;
424 0 : i0=MaxR; if (MaxR<1) MaxR=1;
425 0 : i=MaxR;
426 0 : while (i>=0) {
427 0 : b=Int1+sal_Int16((sal_Int32(Int2-Int1)*sal_Int32(i)) /sal_Int32(MaxR));
428 0 : if (b!=b0) {
429 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
430 0 : rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
431 0 : i0=i; b0=b;
432 : }
433 0 : i--;
434 : }
435 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int1,rOut);
436 0 : rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
437 0 : rOut.SetClipRegion(ClipMerk);
438 0 : } break; // circle
439 : }
440 : }
441 0 : }
442 :
443 0 : void RectType::Draw(OutputDevice& rOut)
444 : {
445 0 : if (L.LMuster!=0) L.LMuster=1; // no line separator here, only on or off
446 0 : SetArea(F,rOut);
447 0 : if (RotationAngle==0) {
448 0 : if ((F.FBFarbe & 0x38)==0 || Radius!=0) {
449 0 : SetLine(L,rOut);
450 0 : rOut.DrawRect(Rectangle(Pos1.x,Pos1.y,Pos2.x,Pos2.y),Radius,Radius);
451 : } else {
452 0 : DrawSlideRect(Pos1.x,Pos1.y,Pos2.x,Pos2.y,F,rOut);
453 0 : if (L.LMuster!=0) {
454 0 : SetLine(L,rOut);
455 0 : rOut.SetFillColor();
456 0 : rOut.DrawRect(Rectangle(Pos1.x,Pos1.y,Pos2.x,Pos2.y));
457 : }
458 : }
459 : } else {
460 0 : Point aPts[4];
461 : sal_uInt16 i;
462 : double sn,cs;
463 0 : sn=sin(double(RotationAngle)*3.14159265359/18000);
464 0 : cs=cos(double(RotationAngle)*3.14159265359/18000);
465 0 : aPts[0]=Point(Pos1.x,Pos1.y);
466 0 : aPts[1]=Point(Pos2.x,Pos1.y);
467 0 : aPts[2]=Point(Pos2.x,Pos2.y);
468 0 : aPts[3]=Point(Pos1.x,Pos2.y);
469 0 : for (i=0;i<4;i++) {
470 0 : RotatePoint(aPts[i],Pos1.x,Pos1.y,sn,cs);
471 : }
472 0 : SetLine(L,rOut);
473 0 : Polygon aPoly(4,aPts);
474 0 : rOut.DrawPolygon(aPoly);
475 : }
476 0 : }
477 :
478 3 : void PolyType::Draw(OutputDevice& rOut)
479 : {
480 3 : if ((Flags & PolyClosBit) !=0) SetArea(F,rOut);
481 3 : SetLine(L,rOut);
482 3 : Polygon aPoly(nPoints);
483 : sal_uInt16 i;
484 3 : for(i=0;i<nPoints;i++) aPoly.SetPoint(Point(EckP[i].x,EckP[i].y),i);
485 3 : if ((Flags & PolyClosBit) !=0) {
486 3 : rOut.DrawPolygon(aPoly);
487 : } else {
488 0 : rOut.DrawPolyLine(aPoly);
489 3 : }
490 3 : }
491 :
492 3 : void SplnType::Draw(OutputDevice& rOut)
493 : {
494 3 : if ((Flags & PolyClosBit) !=0) SetArea(F,rOut);
495 3 : SetLine(L,rOut);
496 3 : Polygon aPoly(0);
497 6 : Polygon aSpln(nPoints);
498 : sal_uInt16 i;
499 3 : for(i=0;i<nPoints;i++) aSpln.SetPoint(Point(EckP[i].x,EckP[i].y),i);
500 3 : if ((Flags & PolyClosBit) !=0) {
501 3 : Spline2Poly(aSpln,true,aPoly);
502 3 : if (aPoly.GetSize()>0) rOut.DrawPolygon(aPoly);
503 : } else {
504 0 : Spline2Poly(aSpln,false,aPoly);
505 0 : if (aPoly.GetSize()>0) rOut.DrawPolyLine(aPoly);
506 3 : }
507 3 : }
508 :
509 0 : void DrawSlideCirc(sal_Int16 cx, sal_Int16 cy, sal_Int16 rx, sal_Int16 ry, ObjAreaType& F, OutputDevice& rOut)
510 : {
511 0 : sal_Int16 x1=cx-rx;
512 0 : sal_Int16 y1=cy-ry;
513 0 : sal_Int16 x2=cx+rx;
514 0 : sal_Int16 y2=cy+ry;
515 :
516 : sal_Int16 i,i0,b,b0;
517 : sal_Int16 Int1,Int2;
518 : sal_Int16 Col1,Col2;
519 :
520 0 : rOut.SetLineColor();
521 0 : Col1=F.FBFarbe & 0x87; Col2=F.FFarbe & 0x87;
522 0 : Int1=100-F.FIntens; Int2=F.FIntens;
523 0 : if (Int1==Int2) {
524 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
525 0 : rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
526 : } else {
527 0 : b0=Int1;
528 0 : switch (F.FBFarbe & 0x38) {
529 : case 0x08: { // vertical
530 0 : vcl::Region ClipMerk=rOut.GetClipRegion();
531 0 : i0=y1;
532 0 : i=y1;
533 0 : while (i<=y2) {
534 0 : b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-y1) /(sal_Int32)(y2-y1+1));
535 0 : if (b!=b0) {
536 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
537 0 : rOut.SetClipRegion(vcl::Region(Rectangle(x1,i0,x2,i-1)));
538 0 : rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
539 0 : i0=i; b0=b;
540 : }
541 0 : i++;
542 : }
543 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
544 0 : rOut.SetClipRegion(vcl::Region(Rectangle(x1,i0,x2,y2)));
545 0 : rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
546 0 : rOut.SetClipRegion(ClipMerk);
547 0 : } break;
548 : case 0x28: { // horizontal
549 0 : vcl::Region ClipMerk=rOut.GetClipRegion();
550 0 : i0=x1;
551 0 : i=x1;
552 0 : while (i<=x2) {
553 0 : b=Int1+sal_Int16((sal_Int32)(Int2-Int1)*(sal_Int32)(i-x1) /(sal_Int32)(x2-x1+1));
554 0 : if (b!=b0) {
555 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
556 0 : rOut.SetClipRegion(vcl::Region(Rectangle(i0,y1,i-1,y2)));
557 0 : rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
558 0 : i0=i; b0=b;
559 : }
560 0 : i++;
561 : }
562 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int2,rOut);
563 0 : rOut.SetClipRegion(vcl::Region(Rectangle(i0,y1,x2,y2)));
564 0 : rOut.DrawEllipse(Rectangle(x1,y1,x2,y2));
565 0 : rOut.SetClipRegion(ClipMerk);
566 0 : } break;
567 :
568 : case 0x18: case 0x38: { // circle
569 : sal_Int16 MaxR;
570 :
571 0 : if (rx<1) rx=1;
572 0 : if (ry<1) ry=1;
573 0 : MaxR=rx;
574 0 : b0=Int2;
575 0 : i0=MaxR;
576 0 : i=MaxR;
577 0 : while (i>=0) {
578 0 : b=Int1+sal_Int16((sal_Int32(Int2-Int1)*sal_Int32(i)) /sal_Int32(MaxR));
579 0 : if (b!=b0) {
580 0 : sal_Int32 temp=sal_Int32(i0)*sal_Int32(ry)/sal_Int32(rx);
581 0 : sal_Int16 j0=sal_Int16(temp);
582 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)b0,rOut);
583 0 : rOut.DrawEllipse(Rectangle(cx-i0,cy-j0,cx+i0,cy+j0));
584 0 : i0=i; b0=b;
585 : }
586 0 : i--;
587 : }
588 0 : SgfAreaColorIntens(F.FMuster,(sal_uInt8)Col1,(sal_uInt8)Col2,(sal_uInt8)Int1,rOut);
589 0 : rOut.DrawEllipse(Rectangle(cx-i0,cy-i0,cx+i0,cy+i0));
590 0 : } break; // circle
591 : }
592 : }
593 0 : }
594 :
595 1 : void CircType::Draw(OutputDevice& rOut)
596 : {
597 1 : Rectangle aRect(Center.x-Radius.x,Center.y-Radius.y,Center.x+Radius.x,Center.y+Radius.y);
598 :
599 1 : if (L.LMuster!=0) L.LMuster=1; // no line pattern here, only on or off
600 1 : SetArea(F,rOut);
601 1 : if ((Flags & 0x03)==CircFull) {
602 1 : if ((F.FBFarbe & 0x38)==0) {
603 1 : SetLine(L,rOut);
604 1 : rOut.DrawEllipse(aRect);
605 : } else {
606 0 : DrawSlideCirc(Center.x,Center.y,Radius.x,Radius.y,F,rOut);
607 0 : if (L.LMuster!=0) {
608 0 : SetLine(L,rOut);
609 0 : rOut.SetFillColor();
610 0 : rOut.DrawEllipse(aRect);
611 : }
612 : }
613 : } else {
614 0 : PointType a,b;
615 0 : Point aStrt,aEnde;
616 : double sn,cs;
617 :
618 0 : a.x=Center.x+Radius.x; a.y=Center.y; b=a;
619 0 : sn=sin(double(StartAngle)*3.14159265359/18000);
620 0 : cs=cos(double(StartAngle)*3.14159265359/18000);
621 0 : RotatePoint(a,Center.x,Center.y,sn,cs);
622 0 : sn=sin(double(StartAngle+RelAngle)*3.14159265359/18000);
623 0 : cs=cos(double(StartAngle+RelAngle)*3.14159265359/18000);
624 0 : RotatePoint(b,Center.x,Center.y,sn,cs);
625 0 : if (Radius.x!=Radius.y) {
626 0 : if (Radius.x<1) Radius.x=1;
627 0 : if (Radius.y<1) Radius.y=1;
628 0 : a.y = a.y - Center.y;
629 0 : b.y = b.y - Center.y;
630 0 : a.y=iMulDiv(a.y,Radius.y,Radius.x);
631 0 : b.y=iMulDiv(b.y,Radius.y,Radius.x);
632 0 : a.y = a.y + Center.y;
633 0 : b.y = b.y + Center.y;
634 : }
635 0 : aStrt=Point(a.x,a.y);
636 0 : aEnde=Point(b.x,b.y);
637 0 : SetLine(L,rOut);
638 0 : switch (Flags & 0x03) {
639 0 : case CircArc : rOut.DrawArc(aRect,aEnde,aStrt); break;
640 : case CircSect:
641 0 : case CircAbsn: rOut.DrawPie(aRect,aEnde,aStrt); break;
642 : }
643 : }
644 1 : }
645 :
646 0 : void BmapType::Draw(OutputDevice& rOut)
647 : {
648 : //ifstream aInp;
649 : unsigned char nSgfTyp;
650 : sal_uInt16 nVersion;
651 : OUString aStr(
652 : reinterpret_cast< char const * >(&Filename[ 1 ]),
653 0 : (sal_Int32)Filename[ 0 ], RTL_TEXTENCODING_UTF8 );
654 0 : INetURLObject aFNam( aStr );
655 :
656 0 : SvStream* pInp = ::utl::UcbStreamHelper::CreateStream( aFNam.GetMainURL( INetURLObject::NO_DECODE ), StreamMode::READ );
657 0 : if ( pInp )
658 : {
659 0 : nSgfTyp=CheckSgfTyp( *pInp,nVersion);
660 0 : switch(nSgfTyp) {
661 : case SGF_BITIMAGE: {
662 0 : GraphicFilter aFlt;
663 0 : Graphic aGrf;
664 0 : aFlt.ImportGraphic(aGrf,aFNam);
665 0 : aGrf.Draw(&rOut,Point(Pos1.x,Pos1.y),Size(Pos2.x-Pos1.x,Pos2.y-Pos1.y));
666 0 : } break;
667 : case SGF_SIMPVECT: {
668 0 : GDIMetaFile aMtf;
669 0 : SgfVectXofs=Pos1.x;
670 0 : SgfVectYofs=Pos1.y;
671 0 : SgfVectXmul=Pos2.x-Pos1.x;
672 0 : SgfVectYmul=Pos2.y-Pos1.y;
673 0 : SgfVectXdiv=0;
674 0 : SgfVectYdiv=0;
675 0 : SgfVectScal=true;
676 0 : SgfVectFilter(*pInp,aMtf);
677 0 : SgfVectXofs=0;
678 0 : SgfVectYofs=0;
679 0 : SgfVectXmul=0;
680 0 : SgfVectYmul=0;
681 0 : SgfVectXdiv=0;
682 0 : SgfVectYdiv=0;
683 0 : SgfVectScal=false;
684 0 : aMtf.Play(&rOut);
685 0 : } break;
686 : }
687 0 : delete pInp;
688 0 : }
689 0 : }
690 :
691 1 : sal_uInt32 GrupType::GetSubPtr()
692 : {
693 1 : return sal_uInt32(SbLo)+0x00010000*sal_uInt32(SbHi);
694 : }
695 :
696 2 : void DrawObjkList( SvStream& rInp, OutputDevice& rOut )
697 : {
698 2 : ObjkType aObjk;
699 2 : sal_uInt16 nGrpCnt=0;
700 2 : bool bEnd=false;
701 8 : do {
702 8 : ReadObjkType( rInp, aObjk );
703 8 : if (!rInp.GetError()) {
704 8 : switch(aObjk.Art) {
705 0 : case ObjStrk: { StrkType aStrk; ReadStrkType( rInp, aStrk ); if (!rInp.GetError()) aStrk.Draw(rOut); } break;
706 0 : case ObjRect: { RectType aRect; ReadRectType( rInp, aRect ); if (!rInp.GetError()) aRect.Draw(rOut); } break;
707 1 : case ObjCirc: { CircType aCirc; ReadCircType( rInp, aCirc ); if (!rInp.GetError()) aCirc.Draw(rOut); } break;
708 : case ObjText: {
709 0 : TextType aText;
710 0 : ReadTextType( rInp, aText );
711 0 : if (!rInp.GetError()) {
712 0 : aText.Buffer=new UCHAR[aText.BufSize+1]; // add one for LookAhead at CK-separation
713 0 : rInp.Read(aText.Buffer, aText.BufSize);
714 0 : if (!rInp.GetError()) aText.Draw(rOut);
715 0 : delete[] aText.Buffer;
716 0 : }
717 0 : } break;
718 : case ObjBmap: {
719 0 : BmapType aBmap;
720 0 : ReadBmapType( rInp, aBmap );
721 0 : if (!rInp.GetError()) {
722 0 : aBmap.Draw(rOut);
723 0 : }
724 0 : } break;
725 : case ObjPoly: {
726 3 : PolyType aPoly;
727 3 : ReadPolyType( rInp, aPoly );
728 3 : if (!rInp.GetError()) {
729 3 : aPoly.EckP=new PointType[aPoly.nPoints];
730 3 : 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 3 : if (!rInp.GetError()) aPoly.Draw(rOut);
735 3 : delete[] aPoly.EckP;
736 3 : }
737 3 : } break;
738 : case ObjSpln: {
739 3 : SplnType aSpln;
740 3 : ReadSplnType( rInp, aSpln );
741 3 : if (!rInp.GetError()) {
742 3 : aSpln.EckP=new PointType[aSpln.nPoints];
743 3 : 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 3 : if (!rInp.GetError()) aSpln.Draw(rOut);
748 3 : delete[] aSpln.EckP;
749 3 : }
750 3 : } break;
751 : case ObjGrup: {
752 1 : GrupType aGrup;
753 1 : ReadGrupType( rInp, aGrup );
754 1 : if (!rInp.GetError()) {
755 1 : rInp.Seek(rInp.Tell()+aGrup.Last); // object appendix
756 1 : if(aGrup.GetSubPtr()!=0L) nGrpCnt++; // DrawObjkList(rInp,rOut );
757 1 : }
758 1 : } break;
759 : default: {
760 0 : aObjk.Draw(rOut); // object name on 2. Screen
761 0 : ObjkOverSeek(rInp,aObjk); // to next object
762 : }
763 : }
764 : } // if rInp
765 8 : if (!rInp.GetError()) {
766 8 : if (aObjk.Next==0L) {
767 3 : if (nGrpCnt==0) bEnd=true;
768 1 : else nGrpCnt--;
769 : }
770 : } else {
771 0 : bEnd=true; // read error
772 : }
773 10 : } while (!bEnd);
774 2 : }
775 :
776 0 : void SkipObjkList(SvStream& rInp)
777 : {
778 0 : ObjkType aObjk;
779 0 : do
780 : {
781 0 : ReadObjkType( rInp, aObjk );
782 0 : if(aObjk.Art==ObjGrup) {
783 0 : GrupType aGrup;
784 0 : ReadGrupType( rInp, aGrup );
785 0 : rInp.Seek(rInp.Tell()+aGrup.Last); // object appendix
786 0 : if(aGrup.GetSubPtr()!=0L) SkipObjkList(rInp);
787 : } else {
788 0 : ObjkOverSeek(rInp,aObjk); // to next object
789 : }
790 0 : } while (aObjk.Next!=0L && !rInp.GetError());
791 0 : }
792 :
793 2 : bool SgfFilterSDrw( SvStream& rInp, SgfHeader&, SgfEntry&, GDIMetaFile& rMtf )
794 : {
795 2 : bool bRet = false;
796 2 : PageType aPage;
797 2 : ScopedVclPtrInstance< VirtualDevice > aOutDev;
798 : OutputDevice* pOutDev;
799 : sal_uLong nStdPos;
800 : sal_uLong nCharPos;
801 : sal_uInt16 Num;
802 :
803 2 : pOutDev=aOutDev.get();
804 2 : DtHdOverSeek(rInp); // read dataheader
805 :
806 2 : nStdPos=rInp.Tell();
807 2 : do { // read standard page
808 2 : ReadPageType( rInp, aPage );
809 2 : if (aPage.nList!=0) SkipObjkList(rInp);
810 2 : } while (aPage.Next!=0L && !rInp.GetError());
811 :
812 2 : nCharPos=rInp.Tell();
813 2 : ReadPageType( rInp, aPage );
814 :
815 2 : rMtf.Record(pOutDev);
816 2 : Num=aPage.StdPg;
817 2 : if (Num!=0) {
818 2 : rInp.Seek(nStdPos);
819 4 : while(Num>1 && aPage.Next!=0L && !rInp.GetError()) { // search standard page
820 0 : ReadPageType( rInp, aPage );
821 0 : if (aPage.nList!=0) SkipObjkList(rInp);
822 0 : Num--;
823 : }
824 2 : ReadPageType( rInp, aPage );
825 2 : if(Num==1 && aPage.nList!=0L) DrawObjkList( rInp,*pOutDev );
826 2 : rInp.Seek(nCharPos);
827 2 : nCharPos=rInp.Tell();
828 2 : ReadPageType( rInp, aPage );
829 : }
830 2 : if (aPage.nList!=0L) DrawObjkList(rInp,*pOutDev );
831 :
832 2 : rMtf.Stop();
833 2 : rMtf.WindStart();
834 4 : MapMode aMap(MAP_10TH_MM,Point(),Fraction(1,4),Fraction(1,4));
835 2 : rMtf.SetPrefMapMode(aMap);
836 2 : rMtf.SetPrefSize(Size((sal_Int16)aPage.Paper.Size.x,(sal_Int16)aPage.Paper.Size.y));
837 2 : bRet=true;
838 4 : return bRet;
839 : }
840 :
841 2 : bool SgfSDrwFilter(SvStream& rInp, GDIMetaFile& rMtf, const INetURLObject& _aIniPath )
842 : {
843 : #if OSL_DEBUG_LEVEL > 1 // check record size. New compiler possibly aligns different!
844 : if (sizeof(ObjTextType)!=ObjTextTypeSize) return false;
845 : #endif
846 :
847 : sal_uLong nFileStart; // offset of SgfHeaders. In general 0.
848 2 : SgfHeader aHead;
849 2 : SgfEntry aEntr;
850 : sal_uLong nNext;
851 2 : bool bRet=false; // return value
852 :
853 2 : INetURLObject aIniPath = _aIniPath;
854 2 : aIniPath.Append(OUString("sgf.ini"));
855 :
856 2 : pSgfFonts = new SgfFontLst;
857 :
858 2 : pSgfFonts->AssignFN( aIniPath.GetMainURL( INetURLObject::NO_DECODE ) );
859 2 : nFileStart=rInp.Tell();
860 2 : ReadSgfHeader( rInp, aHead );
861 2 : if (aHead.ChkMagic() && aHead.Typ==SgfStarDraw && aHead.Version==SGV_VERSION) {
862 2 : nNext=aHead.GetOffset();
863 8 : while (nNext && !rInp.GetError()) {
864 4 : rInp.Seek(nFileStart+nNext);
865 4 : ReadSgfEntry( rInp, aEntr );
866 4 : nNext=aEntr.GetOffset();
867 4 : if (aEntr.Typ==aHead.Typ) {
868 2 : bRet=SgfFilterSDrw( rInp,aHead,aEntr,rMtf );
869 : }
870 : } // while(nNext)
871 : }
872 2 : delete pSgfFonts;
873 2 : return bRet;
874 801 : }
875 :
876 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|