javauis/lcdui_akn/lcdui/src/CMIDFont.cpp
changeset 21 2a9601315dfc
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of CMIDFont for series 60
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <eikenv.h>
       
    20 #include <coemain.h>
       
    21 #include <barsread.h>
       
    22 #include <lcdui.rsg>
       
    23 #include <fontids.hrh>
       
    24 #include <gulfont.h>
       
    25 // API used when font is created
       
    26 #include <AknUtils.h>
       
    27 #include <aknenv.h>
       
    28 // API from CAknLayoutFont related to fonts
       
    29 #include <AknLayoutFont.h>
       
    30 #include <j2me/jdebug.h>
       
    31 #include <aknlayoutscalable_avkon.cdl.h> // for layout data
       
    32 
       
    33 #include "CMIDFont.h"
       
    34 // API used for checking graphic scaling related parameters
       
    35 #include "CMIDMenuHandler.h"
       
    36 #include "CMIDUIManager.h"
       
    37 
       
    38 // Indexes for the font size table below
       
    39 enum TColumnIndexes
       
    40 {
       
    41     EIndexScreenWidth  = 0,
       
    42     EIndexScreenHeight = 1,
       
    43     EIndexSmallFont    = 2,
       
    44     EIndexMediumFont   = 3,
       
    45     EIndexLargeFont    = 4,
       
    46     EResolutionCount   = 6
       
    47 };
       
    48 
       
    49 // Table including the font sizes for known S60 resolutions
       
    50 // The order of the numbers in one table row:
       
    51 // 1. screen width
       
    52 // 2. screen height
       
    53 // 3. small font height
       
    54 // 4. medium font height
       
    55 // 5. large font heigth
       
    56 // This table must be updated when new resolutions become available in S60.
       
    57 const TInt KFontSizes[EResolutionCount][5] =
       
    58 {
       
    59     { 176, 208, 13, 15, 17 }, // Low
       
    60     { 240, 320, 19, 21, 24 }, // QVGA
       
    61     { 320, 480, 25, 28, 32 }, // HVGA
       
    62     { 352, 416, 26, 30, 34 }, // Double
       
    63     { 360, 640, 24, 27, 30 }, // nHD
       
    64     { 480, 640, 32, 36, 41 }  // VGA
       
    65 };
       
    66 
       
    67 // Constant for calculating the font heights when in graphic scaling case
       
    68 // the original MIDlet resolution is smaller than any known S60 resolution.
       
    69 // These are the averages of screen width / font height ratios of
       
    70 // Low, QVGA, Double and HVGA resolutions.
       
    71 const TReal KSmallFontRatioToScreenWidth  = 13.13;
       
    72 const TReal KMediumFontRatioToScreenWidth = 11.58;
       
    73 const TReal KLargeFontRatioToScreenWidth  = 10.18;
       
    74 
       
    75 // Minimum font height. This is used as font height if calculated font
       
    76 // height would be smaller than this.
       
    77 const TInt KMinFontHeight = 11;
       
    78 
       
    79 // Default value of iScalingFactor.
       
    80 const TReal KNonScaled = 1.0;
       
    81 
       
    82 // Zero size (0, 0).
       
    83 #define KZeroSize ::TSize()
       
    84 
       
    85 MMIDFont* CMIDFont::NewL(TUint aStyle, TUint aSize, TInt aFace,
       
    86                          CMIDUIManager* aUIManager, TBool aIsFreeSizeFont)
       
    87 {
       
    88     CMIDFont* font = new(ELeave) CMIDFont(aUIManager);
       
    89     CleanupStack::PushL(font);
       
    90     font->ConstructL(aStyle, aSize, aFace, aIsFreeSizeFont);
       
    91     CleanupStack::Pop(font);
       
    92     return font;
       
    93 }
       
    94 
       
    95 CMIDFont::CMIDFont(CMIDUIManager* aUIManager)
       
    96         : iUIManager(aUIManager), iScalingFactor(KNonScaled)
       
    97 {
       
    98 }
       
    99 
       
   100 /**
       
   101  * @return the MIDP font height - including external leading.
       
   102  */
       
   103 TInt CMIDFont::Height()
       
   104 {
       
   105     const CAknLayoutFont* layFont =  CAknLayoutFont::AsCAknLayoutFontOrNull(Font());
       
   106     // We are using only CAknLayoutFonts, so panic is raised if the layFont is null.
       
   107     ASSERT(layFont);
       
   108     return layFont->TextPaneHeight();
       
   109 }
       
   110 
       
   111 /**
       
   112  * @return vertical distance from top of font to the baseline.
       
   113  */
       
   114 TInt CMIDFont::Baseline()
       
   115 {
       
   116     return Font()->FontMaxAscent();
       
   117 }
       
   118 
       
   119 TInt CMIDFont::Width(const TDesC& aString)
       
   120 {
       
   121     return Font()->TextWidthInPixels(aString);
       
   122 }
       
   123 
       
   124 CMIDFont::~CMIDFont()
       
   125 {
       
   126     const CAknLayoutFont* layFont =  CAknLayoutFont::AsCAknLayoutFontOrNull(iFont);
       
   127     if (layFont)
       
   128     {
       
   129         delete layFont;
       
   130         iFont = NULL;
       
   131     }
       
   132 }
       
   133 
       
   134 void CMIDFont::ConstructL(TUint aStyle, TUint aSize, TInt /*aFace*/,
       
   135                           TBool aIsFreeSizeFont)
       
   136 {
       
   137     // Ensure that menu handler exists. It will be needed later.
       
   138     iUIManager->OpenMenuHandlerL();
       
   139 
       
   140     // saving of flag iUnderline
       
   141     iUnderlined = aStyle & EUnderlined;
       
   142 
       
   143     // We don't need underline flag in aStyle.
       
   144     aStyle &= ~EUnderlined;
       
   145 
       
   146     // saving of size of font
       
   147     iSize = aSize;
       
   148 
       
   149     // saving iIsFreeSizeFont flag
       
   150     iIsFreeSizeFont = aIsFreeSizeFont;
       
   151 
       
   152     // saving of iBold flag
       
   153     if (aStyle & EBold)
       
   154     {
       
   155         iBold = ETrue;
       
   156     }
       
   157     else
       
   158     {
       
   159         iBold = EFalse;
       
   160     }
       
   161 
       
   162     // saving of iItalic flag
       
   163     if (aStyle & EItalic)
       
   164     {
       
   165         iItalic = ETrue;
       
   166     }
       
   167     else
       
   168     {
       
   169         iItalic = EFalse;
       
   170     }
       
   171 
       
   172     // seting of orginal size and scaling factor.
       
   173     SetOrigFontHeight();
       
   174 
       
   175     // checking of this is really resizible font
       
   176     if (iIsFreeSizeFont)
       
   177     {
       
   178         // In case of font with custom height simply set the same value as in iSize
       
   179         iPaneHeight = aSize;
       
   180     }
       
   181     else
       
   182     {
       
   183         // If is not downscaling on and this is not freely resizible font, then we use predefined size of font.
       
   184         iPaneHeight = GetTextPaneHeight(ETrue);
       
   185     }
       
   186 
       
   187     iFont = NULL;
       
   188 
       
   189     // creating of new iFont
       
   190     CreateNewFont();
       
   191 }
       
   192 
       
   193 const CFont* CMIDFont::DefaultFont(const TDefaultId& aId)
       
   194 {
       
   195     if (aId == EDefaultTextId)
       
   196     {
       
   197         return AknLayoutUtils::FontFromId(
       
   198                    AknLayoutScalable_Avkon::form2_mdip_string_pane_t1(1,0).Font(), NULL);
       
   199     }
       
   200     else if (aId == EDefaultLabelId)
       
   201     {
       
   202         return AknLayoutUtils::FontFromId(
       
   203                    AknLayoutScalable_Avkon::form2_midp_label_pane_t1(0).Font(), NULL);
       
   204     }
       
   205     else
       
   206     {
       
   207         ASSERT(0); // unsupported default font id
       
   208         return NULL;
       
   209     }
       
   210 }
       
   211 
       
   212 // deprecated, use DefaultFont(EDefaultLabelId)
       
   213 const CFont* CMIDFont::DefaultLabelFont()
       
   214 {
       
   215     return DefaultFont(EDefaultLabelId);
       
   216 }
       
   217 
       
   218 /**
       
   219  * Returns iFont that is a pointer to CFont object.
       
   220  * Parameter aHighLevelUIComponent indicates whether this method has been called
       
   221  * from a non-high level ui component (Graphics), or a high level UI component (List, StringItem, etc.).
       
   222  */
       
   223 CFont* CMIDFont::Font(TBool aHighLevelComponent)
       
   224 {
       
   225     TBool useScaling = !aHighLevelComponent;
       
   226 
       
   227     TInt paneHeight;
       
   228     if (iIsFreeSizeFont)
       
   229     {
       
   230         // free size font is independent on resolution, so it should not be
       
   231         // re-created if resolution is changed
       
   232         paneHeight = iPaneHeight;
       
   233     }
       
   234     else
       
   235     {
       
   236         // standard font depends on resolution, if resolution is changed
       
   237         // pane height is changed too
       
   238         paneHeight = GetTextPaneHeight(useScaling);
       
   239     }
       
   240 
       
   241     // Check if the font size has changed e.g. because of the dynamic
       
   242     // resolution change. If so re-create the font.
       
   243     if (iPaneHeight != paneHeight)
       
   244     {
       
   245         iPaneHeight = paneHeight;
       
   246         CreateNewFont();
       
   247     }
       
   248 
       
   249     if (iFont)
       
   250     {
       
   251         return iFont;
       
   252     }
       
   253     else
       
   254     {
       
   255         // returns the default font if font creation has failed
       
   256         return const_cast<CFont*>(CMIDFont::DefaultFont(EDefaultTextId));
       
   257     }
       
   258 
       
   259 }
       
   260 
       
   261 /**
       
   262  * CreteNewFont function creates a new iFont object.
       
   263  * Font specification attributes are retrieved from the class member variables.
       
   264  */
       
   265 void CMIDFont::CreateNewFont()
       
   266 {
       
   267     // delete existing iFont object
       
   268     const CAknLayoutFont* layFont =  CAknLayoutFont::AsCAknLayoutFontOrNull(iFont);
       
   269     if (layFont)
       
   270     {
       
   271         delete layFont;
       
   272         iFont = NULL;
       
   273     }
       
   274 
       
   275     // init spec
       
   276     TAknFontSpecification spec(EAknLogicalFontSecondaryFont);
       
   277     // size
       
   278     spec.SetTextPaneHeight(iPaneHeight);
       
   279     // italic
       
   280     if (iItalic)
       
   281         spec.SetPosture(EPostureItalic);
       
   282     // bold
       
   283     if (iBold)
       
   284         spec.SetWeight(EStrokeWeightBold);
       
   285 
       
   286     TInt err = 0;
       
   287     DEBUG("CMIDFont::CreateNewFont - calling CreateLayoutFontFromSpecificationL");
       
   288     TRAP(err, iFont = AknLayoutUtils::CreateLayoutFontFromSpecificationL(spec));   // Now owned by the client code
       
   289     if (err != KErrNone)
       
   290     {
       
   291         DEBUG_INT("CMIDFont::CreateNewFont - Exception from AknLayoutUtils::CreateLayoutFontFromSpecificationL. Error = %d", err);
       
   292     }
       
   293 }
       
   294 
       
   295 TBool CMIDFont::IsUnderlined() const
       
   296 {
       
   297     return iUnderlined;
       
   298 }
       
   299 
       
   300 void CMIDFont::Dispose()
       
   301 {
       
   302     delete this;
       
   303 }
       
   304 
       
   305 
       
   306 /**
       
   307  * This function returns the height of the text pane for the current font size.
       
   308  * The text pane height value is retrieved from the LAF.
       
   309  * If the aScaling is true and graphic scaling is effective in current device screen,
       
   310  * the font height in the original MIDlet resolution is returned.
       
   311  */
       
   312 TInt CMIDFont::GetTextPaneHeight(TBool aScaling)
       
   313 {
       
   314     // iOrigFontHeight > 0 only when orignial MIDlet resolution has been defined in .jad
       
   315     if (aScaling && iOrigFontHeight > 0 &&
       
   316             iUIManager->GetMenuHandler()->IsScalingEffectiveInCurrentScreen())
       
   317     {
       
   318         return iOrigFontHeight;
       
   319     }
       
   320 
       
   321     TInt paneHeight;
       
   322     if (iSize == MMIDFont::ESmall)
       
   323     {
       
   324         //Small size is retrieved from the form item label LAF
       
   325         paneHeight = AknLayoutScalable_Avkon::form2_midp_label_pane_t1(0).H();
       
   326     }
       
   327     else if (iSize == MMIDFont::ELarge)
       
   328     {
       
   329         paneHeight = AknLayoutScalable_Avkon::form2_mdip_string_pane_t1(2,0).H();
       
   330     }
       
   331     else // EMedium
       
   332     {
       
   333         paneHeight = AknLayoutScalable_Avkon::form2_mdip_string_pane_t1(1,0).H();
       
   334     }
       
   335 
       
   336     return paneHeight;
       
   337 }
       
   338 
       
   339 
       
   340 void CMIDFont::SetOrigFontHeight()
       
   341 {
       
   342     iOrigFontHeight = 0;
       
   343 
       
   344     if (!iUIManager->GetMenuHandler()->IsScalingEnabled())
       
   345     {
       
   346         return;
       
   347     }
       
   348 
       
   349     ::TSize origResolution =
       
   350         iUIManager->GetMenuHandler()->GetScalingParameterOrgMIDletScrSize();
       
   351 
       
   352     // ensure that resolution is in portrait orientation
       
   353     ::TSize resolution(Min(origResolution.iWidth, origResolution.iHeight),
       
   354                        Max(origResolution.iWidth, origResolution.iHeight));
       
   355 
       
   356     TInt fontSizeIndex = 0;
       
   357     switch (iSize)
       
   358     {
       
   359     case MMIDFont::ESmall:
       
   360         fontSizeIndex = EIndexSmallFont;
       
   361         break;
       
   362     case MMIDFont::EMedium:
       
   363         fontSizeIndex = EIndexMediumFont;
       
   364         break;
       
   365     case MMIDFont::ELarge:
       
   366         fontSizeIndex = EIndexLargeFont;
       
   367         break;
       
   368     default:
       
   369         break;
       
   370     }
       
   371 
       
   372     // These indexes are for the case that original resolution is not a known
       
   373     // resolution and font height needs to be calculated based on the font heights
       
   374     // in KFontSizes table.
       
   375     TInt smallerResolutionIndex = KErrNotFound;
       
   376     TInt biggerResolutionIndex = KErrNotFound;
       
   377 
       
   378     for (TInt i = 0; i < EResolutionCount && biggerResolutionIndex == KErrNotFound; ++i)
       
   379     {
       
   380         if (KFontSizes[i][EIndexScreenWidth] == resolution.iWidth)
       
   381         {
       
   382             iOrigFontHeight = KFontSizes[i][fontSizeIndex];
       
   383             return;
       
   384         }
       
   385 
       
   386         if (KFontSizes[i][EIndexScreenWidth] < resolution.iWidth)
       
   387         {
       
   388             smallerResolutionIndex = i;
       
   389         }
       
   390         else if (KFontSizes[i][EIndexScreenWidth] > resolution.iWidth &&
       
   391                  biggerResolutionIndex == KErrNotFound)
       
   392         {
       
   393             biggerResolutionIndex = i;
       
   394         }
       
   395     }
       
   396 
       
   397     // Orig resolution is not a known S60 resolution, need to calculate an estimate for
       
   398     // original font height based on the screen width of the original resolution.
       
   399     if (iOrigFontHeight == 0)
       
   400     {
       
   401         // First check if the original MIDlet resolution is smaller than any known
       
   402         // S60 resolution. If so, the original font height estimate is calculated
       
   403         // by using the KXXXFontRatioToScreenWidth constants.
       
   404         if (smallerResolutionIndex == KErrNotFound)
       
   405         {
       
   406             TReal fontSizeRatio = KSmallFontRatioToScreenWidth;
       
   407 
       
   408             switch (iSize)
       
   409             {
       
   410             case MMIDFont::ESmall:
       
   411                 fontSizeRatio = KSmallFontRatioToScreenWidth;
       
   412                 break;
       
   413             case MMIDFont::EMedium:
       
   414                 fontSizeRatio = KMediumFontRatioToScreenWidth;
       
   415                 break;
       
   416             case MMIDFont::ELarge:
       
   417                 fontSizeRatio = KLargeFontRatioToScreenWidth;
       
   418                 break;
       
   419             default:
       
   420                 break;
       
   421             }
       
   422 
       
   423             iOrigFontHeight = TReal(resolution.iWidth) / fontSizeRatio;
       
   424             iOrigFontHeight = Max(KMinFontHeight, iOrigFontHeight);
       
   425         }
       
   426         else if (biggerResolutionIndex == KErrNotFound)
       
   427         {
       
   428             // Original screen width is bigger than the highest resolution in the KFontSizes table.
       
   429             // Use the font size defined for the highest resolution in the table.
       
   430             iOrigFontHeight = KFontSizes[EResolutionCount - 1][fontSizeIndex];
       
   431         }
       
   432         else
       
   433         {
       
   434             // The screen width of the original MIDlet resolution is between 2 known S60 screen
       
   435             // widths. Calculate estimate for font height based on the heights of the 2 known resolutions.
       
   436             TReal fontHeightDelta = KFontSizes[biggerResolutionIndex][fontSizeIndex] -
       
   437                                     KFontSizes[smallerResolutionIndex][fontSizeIndex];
       
   438 
       
   439             TReal screenWidthDelta = KFontSizes[biggerResolutionIndex][EIndexScreenWidth] -
       
   440                                      KFontSizes[smallerResolutionIndex][EIndexScreenWidth];
       
   441 
       
   442             TReal origScreenWidthDelta = resolution.iWidth -
       
   443                                          KFontSizes[smallerResolutionIndex][EIndexScreenWidth];
       
   444 
       
   445             iOrigFontHeight = KFontSizes[smallerResolutionIndex][fontSizeIndex] +
       
   446                               ((origScreenWidthDelta / screenWidthDelta) *
       
   447                                fontHeightDelta);
       
   448         }
       
   449     }
       
   450 }
       
   451 
       
   452 /**
       
   453  * @return ETrue if font is bold, EFalse if not.
       
   454  */
       
   455 TBool CMIDFont::IsBold()
       
   456 {
       
   457     return iBold;
       
   458 }
       
   459 
       
   460 /**
       
   461  * @return ETrue if font is italic, EFalse if not.
       
   462  */
       
   463 TBool CMIDFont::IsItalic()
       
   464 {
       
   465     return iItalic;
       
   466 }
       
   467 // End of File
       
   468