First public contribution.
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
19 #include <bitdrawscaling.h>
20 #include <bitdraworigin.h>
21 #include <bitdrawinterfaceid.h>
28 enum {EScanBufSize=0x80};
30 CFbsDevice::CFbsDevice():
33 iFbs = RFbsSession::GetSession();
37 /** Frees all resources owned by the object prior to its destruction. */
38 EXPORT_C CFbsDevice::~CFbsDevice()
41 delete iTypefaceStore;
42 delete iBitBltMaskedBuffer;
43 delete iGraphicsAccelerator;
46 /** Creates a font and bitmap server graphics context for the device and
49 It is the responsibility of the caller to delete the graphics context when
50 it is no longer needed.
52 @param aGc On return, contains a pointer to the graphics context.
53 @return KErrNone if successful, otherwise, another one of the system-wide error
55 EXPORT_C TInt CFbsDevice::CreateContext(CFbsBitGc*& aGc)
57 TRAPD(ret,aGc = CFbsBitGc::NewL());
62 aGc->ActivateNoJustAutoUpdate(this);
69 /** Gets the device's display mode.
71 @return The display mode of the device. */
72 EXPORT_C TDisplayMode CFbsDevice::DisplayMode() const
74 return iDrawDevice->DisplayMode();
77 /** Gets the size of the device, in pixels.
79 @return The width and height of the device, in pixels */
80 EXPORT_C TSize CFbsDevice::SizeInPixels() const
82 return iDrawDevice->SizeInPixels();
85 /** Compares two rectangles, including their contents.
87 This function is intended for use by test code only.
89 @param aSourceRect The first rectangle to be compared (in this device).
90 @param aDevice The font and bitmap server device in which the second rectangle
92 @param aDeviceRect The second rectangle to be compared.
93 @return ETrue if the rectangles are the same; EFalse otherwise. */
94 EXPORT_C TBool CFbsDevice::RectCompare(const TRect& aSourceRect,
95 const CFbsDevice& aDevice,
96 const TRect& aDeviceRect) const
99 iDrawDevice->GetDrawRect(deviceRect1);
101 aDevice.iDrawDevice->GetDrawRect(deviceRect2);
102 TRect area(deviceRect1);
103 TRect devarea(deviceRect2);
104 TRect tmp(aSourceRect);
105 TRect tmp2(aDeviceRect);
106 tmp.Intersection(area);
107 tmp2.Intersection(devarea);
108 if (tmp!=aSourceRect ||
111 TInt width=aSourceRect.Width();
112 TInt height=aSourceRect.Height();
113 if (width!=aDeviceRect.Width() ||
114 height!=aDeviceRect.Height())
117 TBuf8<EScanBufSize> buf1;
118 TBuf8<EScanBufSize> buf2;
119 TDisplayMode displayMode = iDrawDevice->ScanLineDisplayMode();
120 if (displayMode < EGray256)
121 displayMode = EGray256;
122 else if (displayMode == EColor16)
123 displayMode = EColor256; // Increase the display mode so that each pixel takes at least one byte
124 TInt colsPerBuf=(EScanBufSize*EScanBufSize)/
125 CFbsBitmap::ScanLineLength(EScanBufSize, displayMode);
128 for(TInt row=0;row<height;row++)
134 if ((width-read)<len)
136 GetScanLine(buf1,TPoint(aSourceRect.iTl.iX+read,aSourceRect.iTl.iY+row),len,displayMode);
137 aDevice.GetScanLine(buf2,TPoint(aDeviceRect.iTl.iX+read,aDeviceRect.iTl.iY+row),len,displayMode);
148 /** Adds a font file to the device's typeface store. The specified font
149 file must be accessible to any process, i.e. not located inside an
150 application's private directory.
152 @param aName The name of the font file.
153 @param aId On return, the UID value of the font file.
154 @return KErrNone if successful; otherwise, another of the system-wide error
156 EXPORT_C TInt CFbsDevice::AddFile(const TDesC& aName,TInt& aId)
158 return iTypefaceStore->AddFile(aName,aId);
161 /** Decrements the reference count of a file which was added using
162 AddFile(), and removes the file from the typeface store if the reference count reaches zero.
164 If zero is passed as parameter, then an attempt is made to remove all font objects
165 from the device's typeface store provided none of the fonts in the store are
166 currently accessed, otherwise it has no effect.
168 @param aId The UID value of the font file to be removed. The default is 0. */
169 EXPORT_C void CFbsDevice::RemoveFile(TInt aId)
171 iTypefaceStore->RemoveFile(aId);
174 /** Provides access to a client-side font object in the device's typeface store that most closely
175 matches a font specification.
177 When the font is no longer needed, call @c ReleaseFont().
179 Note that this deprecated function is replaced by the new @c GetNearestFontToDesignHeightInTwips()
180 yielding (virtually) the same result. However clients are strongly encouraged to use the new
181 @c GetNearestFontToMaxHeightInTwips() function instead. This will guarantee that every
182 character within any given text string will fit within the given amount of twips, whereas the design
183 height is an aesthetic unit decided by the font designer without strict physical meaning, which
184 may result in cropped characters.
186 @param aFont On return, points to the font which most closely matches the
188 @param aFontSpec An absolute font specification. Its iHeight member is
189 interpreted as being in twips.
190 @return KErrNone if successful; otherwise, another one of the system-wide error
193 EXPORT_C TInt CFbsDevice::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
195 return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
198 /** Creates a client-side font from those available in the device's typeface
199 store that most closely matches a font specification.
201 When the font is no longer needed, call @c ReleaseFont().
203 Note that this deprecated function is replaced by the new @c GetNearestFontToDesignHeightInPixels()
204 yielding (virtually) the same result. However clients are strongly encouraged to use the new
205 @c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every
206 character within any given text string will fit within the given amount of pixels, whereas the design
207 height is an aesthetic unit decided by the font designer without strict physical meaning, which
208 may result in cropped characters.
210 @param aFont On return, points to the font which most closely matches the
212 @param aFontSpec An absolute font specification. Its iHeight member is
213 interpreted as being in pixels.
214 @return KErrNone if successful; otherwise, another of the system-wide error
217 EXPORT_C TInt CFbsDevice::GetNearestFontInPixels(CFont*& aFont, const TFontSpec& aFontSpec)
219 return GetNearestFontToDesignHeightInPixels(aFont, aFontSpec);
222 /** Creates a client-side font from those available in the device's typeface
223 store that most closely matches a font specification.
225 When the font is no longer needed, call @c ReleaseFont().
227 This new function replaces the deprecated @c GetNearestFontInTwips() yielding (virtually) the
228 same result. However clients are strongly encouraged to use the new
229 @c GetNearestFontToMaxHeightInTwips() function instead. This will guarantee that every
230 character within any given text string will fit within the given amount of twips, whereas the design
231 height is an aesthetic unit decided by the font designer without strict physical meaning, which
232 may result in cropped characters.
234 @param aFont On return, points to the font which most closely matches the
236 @param aFontSpec An absolute font specification. Its iHeight member is
237 interpreted as being in twips.
238 @return KErrNone if successful; otherwise, another one of the system-wide error
240 EXPORT_C TInt CFbsDevice::GetNearestFontToDesignHeightInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
242 return iTypefaceStore->GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
245 /** Creates a client-side font from those available in the device's typeface
246 store that most closely matches a font specification.
248 When the font is no longer needed, call @c ReleaseFont().
250 This new function replaces the deprecated @c GetNearestFontInPixels() yielding (virtually) the
251 same result. However clients are strongly encouraged to use the new
252 @c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every
253 character within any given text string will fit within the given amount of pixels, whereas the design
254 height is an aesthetic unit decided by the font designer without strict physical meaning, which
255 may result in cropped characters.
257 @param aFont On return, points to the font which most closely matches the
259 @param aFontSpec An absolute font specification. Its iHeight member is
260 interpreted as being in pixels.
261 @return KErrNone if successful; otherwise, another one of the system-wide error
263 EXPORT_C TInt CFbsDevice::GetNearestFontToDesignHeightInPixels(CFont*& aFont, const TFontSpec& aFontSpec)
265 return iTypefaceStore->GetNearestFontToDesignHeightInPixels(aFont, aFontSpec);
268 /** Creates a client-side font from those available in the device's typeface
269 store that most closely matches a font specification.
271 When the font is no longer needed, call @c ReleaseFont().
273 The font and bitmap server returns a pointer to the nearest matching font
274 from those available. Matches to max height of font - this does its best
275 to return a font that will fit within the maximum height specified (but
276 note that variations due to hinting algorithms may rarely result in this
277 height being exceeded by up to one pixel). Problems can also be
278 encountered with bitmap fonts where the typeface exists but doesn't have
281 @param aFont On return, the pointer is set to point to the device font which
282 most closely approximates to the required font specification.
283 @param aFontSpec An absolute font specification.
284 @param aMaxHeight The maximum height in twips within which the font must
285 fit - this overrides the height specified in aFontSpec. If maximum height
286 is greater than 1024 pixels, the function returns KErrTooBig. And returns KErrArgument
287 if equals to 1 pixel.
288 @return KErrNone, if successful; otherwise, another of the system-wide error
290 EXPORT_C TInt CFbsDevice::GetNearestFontToMaxHeightInTwips(CFont*& aFont, const TFontSpec& aFontSpec, TInt aMaxHeight)
292 return iTypefaceStore->GetNearestFontToMaxHeightInTwips(aFont, aFontSpec, aMaxHeight);
295 /** Creates a client-side font from those available in the device's typeface
296 store that most closely matches a font specification.
298 When the font is no longer needed, call @c ReleaseFont().
300 The font and bitmap server returns a pointer to the nearest matching font
301 from those available. Matches to max height of font - this does its best
302 to return a font that will fit within the maximum height specified (but
303 note that variations due to hinting algorithms may rarely result in this
304 height being exceeded by up to one pixel). Problems can also be
305 encountered with bitmap fonts where the typeface exists but doesn't have
308 @param aFont On return, the pointer is set to point to the device font which
309 most closely approximates to the required font specification.
310 @param aFontSpec An absolute font specification.
311 @param aMaxHeight The maximum height in pixels within which the font must
312 fit - this overrides the height specified in aFontSpec. If maximum height
313 is greater than 1024 pixels, the function returns KErrTooBig. And returns KErrArgument
314 if equals to 1 pixel.
315 @return KErrNone, if successful; otherwise, another of the system-wide error
317 EXPORT_C TInt CFbsDevice::GetNearestFontToMaxHeightInPixels(CFont*& aFont, const TFontSpec& aFontSpec, TInt aMaxHeight)
319 return iTypefaceStore->GetNearestFontToMaxHeightInPixels(aFont, aFontSpec, aMaxHeight );
322 /** Gets a specific bitmap font, identified by its UID, from the device's typeface
325 When the font is no longer needed, call ReleaseFont().
327 @param aFont On return, set to point to the font.
328 @param aUId The UID identifying the bitmap font.
329 @param aStyle Algorithmic style for the font.
330 @return KErrNone if successful; otherwise, another of the system-wide error
332 EXPORT_C TInt CFbsDevice::GetFontById(CFont*& aFont,TUid aUId,const TAlgStyle& aStyle)
334 return iTypefaceStore->GetFontById(aFont,aUId,aStyle);
337 /** Marks the specified font as no longer needed by the user of the device.
339 As fonts can be shared between applications, this function does not delete
340 the copy of the font from RAM unless the font is only being used by this device.
342 @param aFont A pointer to the font to be released. */
343 EXPORT_C void CFbsDevice::ReleaseFont(CFont* aFont)
345 iTypefaceStore->ReleaseFont(aFont);
348 /** Gets the number of typefaces supported by the device.
350 @return The number of typefaces supported. */
351 EXPORT_C TInt CFbsDevice::NumTypefaces() const
353 return iTypefaceStore->NumTypefaces();
356 /** Gets information about an indexed typeface.
358 @param aTypefaceSupport Provides information about the typeface, including
359 its name and attributes.
360 @param aTypefaceIndex The index of the requested typeface in the device's
361 typeface store; between zero and NumTypefaces() 1 inclusive.
362 @see CGraphicsDevice::TypefaceSupport() */
363 EXPORT_C void CFbsDevice::TypefaceSupport(TTypefaceSupport& aTypefaceSupport,
364 TInt aTypefaceIndex) const
366 iTypefaceStore->TypefaceSupport(aTypefaceSupport,aTypefaceIndex);
369 /** Gets the height of a font in twips.
371 This is an implementation of
372 CGraphicsDevice::FontHeightInTwips(). */
373 EXPORT_C TInt CFbsDevice::FontHeightInTwips(TInt aTypefaceIndex,TInt aHeightIndex) const
375 return iTypefaceStore->FontHeightInTwips(aTypefaceIndex,aHeightIndex);
378 /** Gets the height, in pixels, of the specified typeface at one of its
381 This is an implementation of
382 CBitMapDevice::FontHeightInPixels(). */
383 EXPORT_C TInt CFbsDevice::FontHeightInPixels(TInt aTypefaceIndex,TInt aHeightIndex) const
385 return iTypefaceStore->FontHeightInPixels(aTypefaceIndex,aHeightIndex);
389 Function to add a CLinkedTypefaceSpecification to the font and bitmap server typeface store.
390 @capability ECapabilityWriteDeviceData
393 @param aLinkedTypefaceSpec. The typeface specification to be added.
394 @param aId. A unique ID for the typeface
395 @return an global error code
396 @see CLinkedTypefaceSpecification
398 EXPORT_C TInt CFbsDevice::RegisterLinkedTypeface(const CLinkedTypefaceSpecification& aLinkedTypefaceSpec, TInt& aId)
400 return iTypefaceStore->RegisterLinkedTypeface(aLinkedTypefaceSpec, aId);
403 /** Sets the variable 8 bits per pixel colour palette, replacing the system default
404 one. Only the entries in the system default palette which have corresponding
405 entries in aPalette are overwritten, i.e. if aPalette contains fewer than
406 256 colours, some will remain unchanged. If aPalette has more than 256 entries,
407 the additional entries are ignored.
409 @param aPalette The custom palette.
410 @return KErrNone if successful; otherwise, another of the system-wide error
412 EXPORT_C TInt CFbsDevice::SetCustomPalette(const CPalette* aPalette)
414 TInt ret = iDrawDevice->SetCustomPalette(aPalette);
417 // Graphics accelerator doesn't currently support changing palettes,
418 // so delete it if the palette is successfully changed.
419 delete iGraphicsAccelerator;
420 iGraphicsAccelerator = NULL;
426 The method gets a scanline and puts the scanline data into aBuf.
428 @param aBuf The destination buffer. It should be with enough length to collect
429 requested scanline data.
430 @param aPixel The first pixel of the requested scanline data
431 @param aLength The length in pixels of requested data
432 @param aDispMode requested scanline should be converted regarding aDispMode parameter
434 void CFbsDevice::DoGetScanLine(TDes8& aBuf,const TPoint& aPixel,TInt aLength,
435 TDisplayMode aDispMode)
438 iDrawDevice->GetDrawRect(deviceRect);
439 if (aPixel.iY < deviceRect.iTl.iY || aPixel.iY > deviceRect.iBr.iY)
443 TInt bitsPerPixel = 0;
449 byteLength = aLength / 8 + (aLength % 8 ? 1 : 0);
453 byteLength = aLength / 4 + (aLength % 4 ? 1 : 0);
458 byteLength = aLength / 2 + (aLength % 2 ? 1 : 0);
463 byteLength = aLength;
468 byteLength = aLength * 2;
472 byteLength = aLength * 3;
479 byteLength = aLength * 4;
483 BG_PANIC_ALWAYS(EBitgdiPanicInvalidDisplayMode);
486 if (byteLength > aBuf.MaxLength())
488 TInt pixelsMaxCount = (aBuf.MaxLength() * 8) / bitsPerPixel;
489 if(aLength > pixelsMaxCount)
491 aLength = pixelsMaxCount;
497 aBuf.SetLength(byteLength);
500 TInt x1 = Max(aPixel.iX, deviceRect.iTl.iX);
501 TInt x2 = Min(aPixel.iX + aLength, deviceRect.iBr.iX);
505 TUint8* vals = (TUint8*)(aBuf.Ptr());
506 iDrawDevice->ReadLine(x1,aPixel.iY,x2 - x1,vals,aDispMode);
509 void CFbsDevice::TruncateRect(TRect& aRect)
511 TInt width = iDrawDevice->SizeInPixels().iWidth << 4;
512 TInt height = iDrawDevice->SizeInPixels().iHeight << 4;
514 aRect.iTl.iX = Min(aRect.iTl.iX,width);
515 aRect.iTl.iY = Min(aRect.iTl.iY,height);
516 aRect.iBr.iX = Min(aRect.iBr.iX,width);
517 aRect.iBr.iY = Min(aRect.iBr.iY,height);
522 aRect.iTl.iX = Max(aRect.iTl.iX,width);
523 aRect.iTl.iY = Max(aRect.iTl.iY,height);
524 aRect.iBr.iX = Max(aRect.iBr.iX,width);
525 aRect.iBr.iY = Max(aRect.iBr.iY,height);
528 TBool CFbsDevice::SetOrientation(CFbsBitGc::TGraphicsOrientation aOrientation)
530 TBool ret = iDrawDevice->SetOrientation((CFbsDrawDevice::TOrientation)aOrientation);
532 iOrientation = aOrientation;
537 Depending on the current graphics hardware this
538 will return one of the 16M video modes defined in
539 TDisplayMode, or ENone if a 16M video mode is not supported.
541 @return a 16M display mode or ENone.
543 EXPORT_C TDisplayMode CFbsDevice::DisplayMode16M()
545 return CFbsDrawDevice::DisplayMode16M();
549 Sets scaling factor by which the drawing device should scale the drawing images.
550 If you want to un-scale the device, call SetScalingFactor() with Origin (0,0),
551 factorX = 1, factorY = 1, divisorX = 1, divisorY = 1.
553 Note: The existing graphics acceleration interface does not have support for scaling.
555 Note: All graphics contexts, already created by the scaled device, should be
556 re-activated calling CFbsBitGc::Activate().
558 @param aOrigin Specifies physical coordinates of the new scaling origin
559 of the drawing device. The drawing device maps the logical point [0, 0] to
560 the "aOrigin" physical point .
561 @param aFactorX Scaling factor for the X-axis of the screen device.
562 @param aFactorY Scaling factor for the y-axis of the screen device.
563 @param aDivisorX Not used. Should be set to 1.
564 @param aDivisorY Not used. Should be set to 1.
565 @return KErrNone If the method succeeds.
566 KErrNotSupported The drawing device does not have scaling capabilities.
568 EXPORT_C TInt CFbsDevice::SetScalingFactor(const TPoint& aOrigin,
569 TInt aFactorX, TInt aFactorY,
570 TInt aDivisorX, TInt aDivisorY)
572 //This class takes care about setting scaling and origin and restoring the original values
573 //if some of the operations fails.
577 TInitializer(CFbsDrawDevice* aDrawDevice) :
578 iScalingSettings(NULL), iOriginInterface(NULL),
580 iFx(1), iFy(1), iDivX(1), iDivY(1),
582 {//Acquire the interfaces and save the original settings. They will be used if the initialization fails.
583 iError = aDrawDevice->GetInterface(KScalingSettingsInterfaceID,
584 reinterpret_cast <TAny*&> (iScalingSettings));
585 if(iError == KErrNone)
587 BG_ASSERT_DEBUG_INVARIANT(iScalingSettings);
588 iScalingSettings->Get(iFx, iFy, iDivX, iDivY);
589 iError = aDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID,
590 reinterpret_cast <TAny*&> (iOriginInterface));
591 if(iError == KErrNone)
593 BG_ASSERT_DEBUG_INVARIANT(iOriginInterface);
594 iOriginInterface->Get(iOrigin);
599 {//Restore the original settings if setting of the new ones had failed.
600 if(iError != KErrNone)
604 (void)iScalingSettings->Set(iFx, iFy, iDivX, iDivY);
608 (void)iOriginInterface->Set(iOrigin);
612 void SetScalingFactor(TInt aFactorX, TInt aFactorY, TInt aDivisorX, TInt aDivisorY)
614 if(iError == KErrNone)
616 iError = iScalingSettings->Set(aFactorX, aFactorY, aDivisorX, aDivisorY);
619 void SetOrigin(const TPoint& aOrigin)
621 if(iError == KErrNone)
623 iError = iOriginInterface->Set(aOrigin);
631 MScalingSettings* iScalingSettings;
632 MDrawDeviceOrigin* iOriginInterface;
634 TInt iFx, iFy, iDivX, iDivY;
637 TInitializer initializer(iDrawDevice);
638 initializer.SetScalingFactor(aFactorX, aFactorY, aDivisorX, aDivisorY);
639 initializer.SetOrigin(aOrigin);
640 TInt err = initializer.Error();
641 if(err == KErrNone &&
642 (aFactorX != aDivisorX || aFactorY != aDivisorY || aOrigin.iX != 0 || aOrigin.iY != 0))
644 //Graphics accelerator interface doesn't have support for scaling&origin.
645 delete iGraphicsAccelerator;
646 iGraphicsAccelerator = NULL;
652 Gets logical coordinates of the drawing rectangle.
653 If the device is not scaled, logocal coordinates of the drawing rectangle are the
654 same as its physical coordinates.
655 @param aRect Upon return aRect contains drawing rectangle logical coordinates.
657 EXPORT_C void CFbsDevice::GetDrawRect(TRect& aRect) const
659 iDrawDevice->GetDrawRect(aRect);
663 An overloaded version of DrawingBegin(TBool). Similarly to that method, calls to
664 DrawingBegin(const CFbsBitmap*, TBool) must be paired with a subsequent call to
665 DrawingEnd(const CFbsBitmap*, TBool). Also, code must not leave between a
666 DrawingBegin(const CFbsBitmap*, TBool) - DrawingEnd(const CFbsBitmap*, TBool) pair.
667 @param aBitmap An additional parameter compared to the basic overload.
668 aBitmap is a pointer to a CFbsBitmap object to be frozen. If a null pointer
669 is given then the method panics.
670 @param aAlways Not used.
672 @see CFbsBitmapDevice::DrawingBegin()
674 void CFbsDevice::DrawingBegin(const CFbsBitmap* aBitmap, TBool /*aAlways*/)
676 BG_ASSERT_DEBUG(aBitmap, EBitgdiPanicInvalidBitmap);
678 aBitmap->BeginDataAccess();
683 This must always be called after DrawingBegin(const CFbsBitmap*, TBool).
684 Like DrawingBegin(const CFbsBitmap*, TBool) it will panic in debug builds
685 if passed a null pointer.
686 @param aBitmap A pointer to a CFbsBitmap object to be unfrozen.
687 @param aAlways Not used.
689 @see CFbsBitmapDevice::DrawingEnd()
691 void CFbsDevice::DrawingEnd(const CFbsBitmap* aBitmap, TBool /*aAlways*/)
693 BG_ASSERT_DEBUG(aBitmap, EBitgdiPanicInvalidBitmap);
695 aBitmap->EndDataAccess(ETrue);
700 Used to set an offset
701 @param aOrigin The offset to give
702 @return KErrNone on success, otherwise a system wide error code
704 EXPORT_C TInt CFbsDevice::SetDrawDeviceOffset(const TPoint& aOrigin)
710 MDrawDeviceOrigin* drawDevice=NULL;
711 if ( iDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID,reinterpret_cast<void*&>(drawDevice))<KErrNone
715 return KErrNotSupported;
717 drawDevice->Set(aOrigin);