1 /************************************************************************/
2 /*									*/
3 /*  Open the objects embedded in a document.				*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"docLayoutConfig.h"
8 
9 #   include	<stdio.h>
10 
11 #   include	<sioMemory.h>
12 #   include	<sioHex.h>
13 #   include	<drawMetafile.h>
14 #   include	"docLayoutObject.h"
15 
16 #   include	<appDebugon.h>
17 
18 #   include	<docBuf.h>
19 #   include	<docPageGrid.h>
20 #   include	<docTreeNode.h>
21 #   include	<geoGrid.h>
22 #   include	<geoUnits.h>
23 #   include	<docShape.h>
24 #   include	<docObjectProperties.h>
25 #   include	<bmio.h>
26 
27 /************************************************************************/
28 /*									*/
29 /*  Make the bitmap for an image.					*/
30 /*  Make a name for an image.						*/
31 /*									*/
32 /************************************************************************/
33 
docGetBitmap(bmReadBitmap readBitmap,RasterImage * ri,const MemoryBuffer * mb)34 static int docGetBitmap(	bmReadBitmap		readBitmap,
35 				RasterImage *		ri,
36 				const MemoryBuffer *	mb )
37     {
38     int			rval= 0;
39     int			res;
40 
41     SimpleInputStream *	sisMem= (SimpleInputStream *)0;
42     SimpleInputStream *	sisBitmap= (SimpleInputStream *)0;
43 
44     sisMem= sioInMemoryOpen( mb );
45     if  ( ! sisMem )
46 	{ XDEB(sisMem); rval= -1; goto ready;	}
47 
48     sisBitmap= sioInHexOpen( sisMem );
49     if  ( ! sisBitmap )
50 	{ XDEB(sisBitmap); rval= -1; goto ready;	}
51 
52     res= (*readBitmap)( &(ri->riDescription), &(ri->riBytes), sisBitmap );
53 
54     if  ( res < 0 )
55 	{ LDEB(res); rval= -1;	}
56 
57   ready:
58 
59     if  ( sisBitmap )
60 	{ sioInClose( sisBitmap );	}
61     if  ( sisMem )
62 	{ sioInClose( sisMem );	}
63 
64     return rval;
65     }
66 
docGetBitmapForObjectData(int kind,RasterImage * ri,const MemoryBuffer * mb)67 int docGetBitmapForObjectData(	int			kind,
68 				RasterImage *		ri,
69 				const MemoryBuffer *	mb )
70     {
71     switch( kind )
72 	{
73 	case DOCokPICTWMETAFILE:
74 	    if  ( docGetBitmap( appMetaPlayWmfImg, ri, mb )	)
75 		{ LDEB(1); return -1;	}
76 
77 	    break;
78 
79 	case DOCokPICTPNGBLIP:
80 	    if  ( docGetBitmap( bmPngReadPng, ri, mb )	)
81 		{ LDEB(1); return -1;	}
82 	    break;
83 
84 	case DOCokPICTJPEGBLIP:
85 	    if  ( docGetBitmap( bmJpegReadJfif, ri, mb )	)
86 		{ LDEB(1); return -1;	}
87 
88 	    break;
89 
90 	case DOCokMACPICT:
91 	case DOCokPICTEMFBLIP:
92 	default:
93 	    LDEB(kind); return -1;
94 	}
95 
96     return 0;
97     }
98 
docGetBitmapForObject(InsertedObject * io)99 int docGetBitmapForObject(	InsertedObject *	io )
100     {
101     switch( io->ioKind )
102 	{
103 	case DOCokPICTWMETAFILE:
104 	    if  ( ! io->ioRasterImage.riBytes				&&
105 		  docGetBitmapForObjectData( io->ioKind,
106 			&(io->ioRasterImage), &(io->ioObjectData) )	)
107 		{ LDEB(1); return 0;	}
108 
109 	    if  ( io->ioRasterImage.riBytes )
110 		{ io->ioPictureProperties.pipMetafileIsBitmap= 1;	}
111 
112 	    break;
113 
114 	case DOCokPICTPNGBLIP:
115 	case DOCokPICTJPEGBLIP:
116 	    if  ( ! io->ioRasterImage.riBytes				&&
117 		  docGetBitmapForObjectData( io->ioKind,
118 			&(io->ioRasterImage), &(io->ioObjectData) )	)
119 		{ LDEB(1); return 0;	}
120 	    break;
121 
122 	case DOCokOLEOBJECT:
123 	    if  ( io->ioResultKind == DOCokPICTWMETAFILE )
124 		{
125 		if  ( ! io->ioRasterImage.riBytes			&&
126 		      docGetBitmapForObjectData( io->ioResultKind,
127 			    &(io->ioRasterImage), &(io->ioResultData) )	)
128 		    { LDEB(1); return 0;	}
129 
130 		if  ( io->ioRasterImage.riBytes )
131 		    { io->ioPictureProperties.pipMetafileIsBitmap= 1;	}
132 
133 		return 0;
134 		}
135 
136 	    if  ( io->ioResultKind == DOCokPICTPNGBLIP	||
137 		  io->ioResultKind == DOCokPICTJPEGBLIP )
138 		{
139 		if  ( ! io->ioRasterImage.riBytes			&&
140 		      docGetBitmapForObjectData( io->ioResultKind,
141 			    &(io->ioRasterImage), &(io->ioResultData) )	)
142 		    { LDEB(1); return 0;	}
143 
144 		return 0;
145 		}
146 
147 	    return 0;
148 
149 	case DOCokMACPICT:
150 	case DOCokPICTEMFBLIP:
151 	default:
152 	    LDEB(io->ioKind); return 0;
153 	}
154 
155     return 0;
156     }
157 
docCheckObjectLayout(int * pFixed,InsertedObject * io)158 int docCheckObjectLayout(	int *			pFixed,
159 				InsertedObject *	io )
160     {
161     PictureProperties *	pip= &(io->ioPictureProperties);
162     int			fixed= 0;
163 
164     if  ( io->ioKind == DOCokMACPICT )
165 	{
166 	if  ( pip->pipTwipsWide == 0 )
167 	    { pip->pipTwipsWide= 20* pip->pip_xWinExt; fixed= 1;	}
168 	if  ( pip->pipTwipsHigh == 0 )
169 	    { pip->pipTwipsHigh= 20* pip->pip_yWinExt; fixed= 1;	}
170 	}
171 
172     if  ( io->ioKind == DOCokDRAWING_SHAPE )
173 	{
174 	const DrawingShape *	ds= io->ioDrawingShape;
175 
176 	if  ( ! ds )
177 	    { LXDEB(io->ioKind,io->ioDrawingShape);	}
178 	else{
179 	    DocumentRectangle	drTwips;
180 
181 	    docPlaceRootShapeRect( &drTwips, &(io->ioDrawingShape->dsShapeProperties), 0, 0 );
182 
183 	    if  ( io->ioTwipsWide == 0 )
184 		{
185 		io->ioTwipsWide= drTwips.drX1- drTwips.drX0+ 1;
186 		fixed= 1;
187 		}
188 	    if  ( io->ioTwipsHigh == 0 )
189 		{
190 		io->ioTwipsHigh= drTwips.drY1- drTwips.drY0+ 1;
191 		fixed= 1;
192 		}
193 	    }
194 	}
195 
196     if  ( ( pip->pipTwipsWide == 0		||
197 	    pip->pipTwipsHigh == 0		)	&&
198 	  ( io->ioKind == DOCokPICTPNGBLIP	||
199 	    io->ioKind == DOCokPICTJPEGBLIP	)	)
200 	{
201 	if  ( ! io->ioRasterImage.riBytes	&&
202 	      docGetBitmapForObject( io )	)
203 	    { LDEB(1);	}
204 	else{
205 	    bmRectangleSizeTwips( &(pip->pipTwipsWide), &(pip->pipTwipsHigh),
206 				&(io->ioRasterImage.riDescription),
207 				io->ioRasterImage.riDescription.bdPixelsWide,
208 				io->ioRasterImage.riDescription.bdPixelsHigh );
209 	    fixed= 1;
210 	    }
211 	}
212 
213     if  ( io->ioTwipsWide == 0 )
214 	{ io->ioTwipsWide= pip->pipTwipsWide; fixed= 1;	}
215     if  ( io->ioTwipsHigh == 0 )
216 	{ io->ioTwipsHigh= pip->pipTwipsHigh; fixed= 1;	}
217 
218     *pFixed= fixed;
219     return 0;
220     }
221 
222 /************************************************************************/
223 /*									*/
224 /*  Scale an inserted object to fit where we want to place it.		*/
225 /*									*/
226 /*  1)  If the object fits on the page at its current scale, nothing	*/
227 /*	needs to be done. Apparently this was the case before as well,	*/
228 /*	as otherwise the ioScale[XY]Used would not have been equal to	*/
229 /*	ioScale[XY]Set.							*/
230 /*  2)  Otherwise scale the object to fit on the page. X and Y scale	*/
231 /*	are the same, irrespective of the original scaling.		*/
232 /*									*/
233 /************************************************************************/
234 
docLayoutScaleObjectToFitParagraphFrame(int * pChanged,InsertedObject * io,int pageHigh,const DocumentRectangle * drParaContent)235 void docLayoutScaleObjectToFitParagraphFrame(
236 				int *				pChanged,
237 				InsertedObject *		io,
238 				int				pageHigh,
239 				const DocumentRectangle *	drParaContent )
240     {
241     int		textWideTwips= drParaContent->drX1- drParaContent->drX0;
242 
243     int		objectWideTwips= ( io->ioScaleXSet* io->ioTwipsWide )/ 100.0;
244     int		objectHighTwips= ( io->ioScaleYSet* io->ioTwipsHigh )/ 100.0;
245 
246     double	scaleX;
247     double	scaleY;
248     int		scaleMax;
249 
250     int		prevXScaleUsed= io->ioScaleXUsed;
251     int		prevYScaleUsed= io->ioScaleYUsed;
252 
253     PictureProperties *	pip= &(io->ioPictureProperties);
254 
255     /*  1  */
256     if  ( io->ioScaleXUsed == io->ioScaleXSet	&&
257 	  io->ioScaleYUsed == io->ioScaleYSet	&&
258 	  objectWideTwips <= textWideTwips	&&
259 	  objectHighTwips <= pageHigh		)
260 	{ *pChanged= 0; return;	}
261 
262     /*  2  */
263     scaleX= (double)textWideTwips/ (double)io->ioTwipsWide;
264     scaleY= (double)pageHigh/ (double)io->ioTwipsHigh;
265 
266     if  ( scaleY > scaleX )
267 	{ scaleY=  scaleX;	}
268     scaleMax= (int)( 99* scaleY );
269 
270     io->ioScaleXUsed= io->ioScaleXSet;
271     io->ioScaleYUsed= io->ioScaleYSet;
272 
273     pip->pipScaleXUsed= io->ioScaleXUsed;
274     pip->pipScaleYUsed= io->ioScaleYUsed;
275 
276     if  ( scaleMax < io->ioScaleXUsed	||
277 	  scaleMax < io->ioScaleYUsed	)
278 	{
279 	if  ( io->ioScaleXUsed > scaleMax )
280 	    { io->ioScaleXUsed= scaleMax;	}
281 	if  ( io->ioScaleYUsed > scaleMax )
282 	    { io->ioScaleYUsed= scaleMax;	}
283 
284 	if  ( io->ioScaleXUsed < 1 )
285 	    { io->ioScaleXUsed=  1;	}
286 	if  ( io->ioScaleYUsed < 1 )
287 	    { io->ioScaleYUsed=  1;	}
288 
289 	pip->pipScaleXUsed= io->ioScaleXUsed;
290 	pip->pipScaleYUsed= io->ioScaleYUsed;
291 	}
292 
293     if  ( io->ioScaleXUsed != prevXScaleUsed	||
294 	  io->ioScaleYUsed != prevYScaleUsed	)
295 	{ *pChanged= 1;	}
296     else{ *pChanged= 0;	}
297 
298     return;
299     }
300 
docScaleObjectToParagraph(BufferDocument * bd,BufferItem * paraBi,double xfac,InsertedObject * io)301 void docScaleObjectToParagraph( BufferDocument *		bd,
302 				BufferItem *			paraBi,
303 				double				xfac,
304 				InsertedObject *		io )
305     {
306     ParagraphFrame		pf;
307 
308     PictureProperties *		pip= &(io->ioPictureProperties);
309 
310     BlockFrame			bf;
311     int				changed= 0;
312 
313     int				pageHigh;
314 
315     docBlockFrameTwips( &bf, paraBi, bd,
316 				    paraBi->biTopPosition.lpPage,
317 				    paraBi->biTopPosition.lpColumn );
318 
319     docParagraphFrameTwips( &pf, &bf, paraBi );
320 
321     pageHigh= bf.bfPageGeometry.dgPageHighTwips-
322 			    bf.bfPageGeometry.dgTopMarginTwips-
323 			    bf.bfPageGeometry.dgBottomMarginTwips;
324 
325     docLayoutScaleObjectToFitParagraphFrame( &changed,
326 				    io, pageHigh, &(pf.pfParaContentRect) );
327 
328     pip->pipScaleXUsed= io->ioScaleXUsed;
329     pip->pipScaleYUsed= io->ioScaleYUsed;
330 
331     io->ioPixelsWide= COORDtoGRID( xfac,
332 				( io->ioScaleXUsed* pip->pipTwipsWide )/ 100 );
333     io->ioPixelsHigh= COORDtoGRID( xfac,
334 				( io->ioScaleYUsed* pip->pipTwipsHigh )/ 100 );
335     if  ( io->ioPixelsWide < 1 )
336 	{ io->ioPixelsWide=  1;	}
337     if  ( io->ioPixelsHigh < 1 )
338 	{ io->ioPixelsHigh=  1;	}
339 
340     pip->pip_xWinExt= (int) ( ( 100000.0* pip->pipTwipsWide )/ TWIPS_PER_M );
341     pip->pip_yWinExt= (int) ( ( 100000.0* pip->pipTwipsHigh )/ TWIPS_PER_M );
342 
343     return;
344     }
345 
346