webengine/osswebengine/WebCore/platform/symbian/FontSymbian.cpp
changeset 0 dd21522fd290
child 8 7c90e6132015
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2006 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 the License "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:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "config.h"
       
    20 #include "Font.h"
       
    21 #include "TextStyle.h"
       
    22 #include "FontData.h"
       
    23 #include "FontFallbackList.h"
       
    24 #include "GraphicsContext.h"
       
    25 #include "IntRect.h"
       
    26 #include "WebCoreGraphicsContext.h"
       
    27 #include <e32std.h>
       
    28 #include <BITSTD.H>
       
    29 #include <gdi.h>
       
    30 #include "StaticObjectsContainer.h"
       
    31 #include "PictographSymbian.h"
       
    32 #include "ZoomFactor.h"
       
    33 #include "PlatformFontCache.h"
       
    34 
       
    35 namespace WebCore {
       
    36 
       
    37 static void notSupported() { __ASSERT_ALWAYS( 0, User::Panic( _L("Font:"), 1 ) ); }
       
    38 
       
    39 void Font::drawGlyphs(GraphicsContext* graphicsContext, const FontData* font, const GlyphBuffer& glyphBuffer,
       
    40                       int from, int numGlyphs, const FloatPoint& point) const
       
    41 {
       
    42     notSupported();
       
    43 }
       
    44 
       
    45 FloatRect Font::selectionRectForComplexText(const TextRun& run, const TextStyle& style, const IntPoint& point, int h, int from, int to) const
       
    46 {
       
    47     float b = 0;
       
    48     if (from>0) {
       
    49         TextRun begin(run.characters(), from);
       
    50         b = floatWidthForComplexText(begin, style);
       
    51     }
       
    52 
       
    53     TextRun end(run.characters() + from, to - from);
       
    54     float w = floatWidthForComplexText(end, style);        
       
    55             
       
    56     FloatRect rect(b + point.x(), point.y(), w, h);
       
    57 
       
    58     return rect;
       
    59 }
       
    60 
       
    61 void Font::drawComplexText(GraphicsContext* graphicsContext, const TextRun& run, const TextStyle& style, const FloatPoint& point, int from, int to) const                          
       
    62 {
       
    63     PlatformFontCache* cache = StaticObjectsContainer::instance()->fontCache();
       
    64     CFont* font = cache->zoomedFont(m_fontDescription, cache->fontZoomFactor());
       
    65     // RenderBlock::layoutColumns create a 0 platform context to do a faked paint
       
    66     // during layout - weird stuff :)
       
    67     if (!graphicsContext->platformContext())
       
    68         return;
       
    69 
       
    70     CFbsBitGc& bitgc = graphicsContext->platformContext()->gc();
       
    71     Color c = graphicsContext->fillColor();
       
    72     bitgc.SetPenColor( TRgb( c.red(), c.green(), c.blue(), c.alpha() ) );
       
    73     bitgc.UseFontNoDuplicate( static_cast<const CFbsBitGcFont*>(font) );
       
    74 
       
    75     TPoint startPos = point;
       
    76     if (from) {
       
    77         
       
    78         // the text run before the selection
       
    79         TextRun leftRun(run.characters(), from);
       
    80         // the selection start point
       
    81         startPos.iX += floatWidthForComplexText(leftRun, style);
       
    82     }
       
    83     
       
    84     TPtrC str( (const TUint16*)(run.characters() + from), to - from);
       
    85     
       
    86     TInt numSpaces(0);
       
    87     TInt indexOfFirstNonRegularSpace(-1);
       
    88     TInt strLength(str.Length());
       
    89     
       
    90     // a) search for nbsp and similar
       
    91     // b) count the spaces for word spacing
       
    92     for( TInt n = 0; n<strLength; ++n) {
       
    93     
       
    94         if ( str[n] == ' ' ) {
       
    95             numSpaces++;
       
    96         }
       
    97         else if( TChar(str[n]).IsSpace() ) {
       
    98     
       
    99             if (indexOfFirstNonRegularSpace==-1) {
       
   100                 indexOfFirstNonRegularSpace = n;
       
   101             }
       
   102             numSpaces++;
       
   103             if( m_wordSpacing==0 || style.padding()==0 ) {
       
   104                 break;
       
   105             }
       
   106         }
       
   107     }
       
   108 
       
   109     // letter spacing
       
   110     bitgc.SetCharJustification(m_letterSpacing*str.Length(),str.Length());
       
   111     // word spacing
       
   112     bitgc.SetWordJustification(m_wordSpacing*numSpaces + style.padding(), numSpaces);
       
   113 
       
   114     // see if we need a temporary buffer
       
   115     if( indexOfFirstNonRegularSpace > -1 || isSmallCaps() || style.rtl()){
       
   116         HBufC* text = 0;
       
   117         text = str.Alloc();
       
   118         if (text){
       
   119             
       
   120             TPtr newStr(text->Des());
       
   121             if (isSmallCaps()) {
       
   122                 // proper small caps implementation would use smaller font, but that get complicated
       
   123                 // just upper case for now
       
   124                 newStr.UpperCase();
       
   125             }
       
   126 
       
   127             // if we have non-regular spaces (nbsp, tab, etc.) we need to make a copy
       
   128             // and replace them with regular spaces. otherwise they show up as boxes.
       
   129             if (indexOfFirstNonRegularSpace > -1) {
       
   130                 for(; indexOfFirstNonRegularSpace<strLength; ++indexOfFirstNonRegularSpace ) {
       
   131                     if( TChar(newStr[indexOfFirstNonRegularSpace]).IsSpace() ) {
       
   132                         newStr[indexOfFirstNonRegularSpace] = ' ';
       
   133                     }
       
   134                 }
       
   135             }
       
   136             
       
   137             if (style.rtl()) {
       
   138                 TBidiText* bidiText = TBidiText::NewL( newStr, 1, TBidiText::ERightToLeft );
       
   139                 bidiText->WrapText(xForm(width(run)), *font );
       
   140                 bitgc.DrawText( bidiText->DisplayText(),xForm(startPos)); 
       
   141                 delete bidiText;      
       
   142             }
       
   143             else{
       
   144                 bitgc.DrawText( newStr, xForm(startPos) );   	
       
   145             }
       
   146             
       
   147             if (graphicsContext && StaticObjectsContainer::instance()->pictograph())
       
   148                 StaticObjectsContainer::instance()->pictograph()->DrawPictographsInText(graphicsContext->platformContext(), bitgc, *font, newStr, startPos );
       
   149             
       
   150             delete text;
       
   151         }
       
   152         
       
   153     }else {
       
   154         bitgc.DrawText( str, xForm(startPos) );
       
   155         if (graphicsContext && StaticObjectsContainer::instance()->pictograph())        
       
   156             StaticObjectsContainer::instance()->pictograph()->DrawPictographsInText(graphicsContext->platformContext(), bitgc, *font, str, startPos );
       
   157     }
       
   158         
       
   159     bitgc.DiscardFont();
       
   160 }
       
   161 
       
   162 inline float floatWidthForComplexTextSymbian(const Font* f, const TextRun& run,  const TextStyle& style, int maxWidth, int& chars){
       
   163     const CFont& font( f->primaryFont()->platformData() );
       
   164     TPtrC str( (const TUint16*)(run.characters()), run.length());
       
   165     
       
   166     TInt numSpaces(0);
       
   167     TInt indexOfFirstNonRegularSpace(-1);
       
   168     TInt strLength(str.Length());
       
   169     // count the spaces for word spacing
       
   170     // a) search for nbsp and similar
       
   171     // b) count the spaces for word spacing
       
   172     for( TInt n = 0; n<strLength; ++n)
       
   173         {
       
   174         if ( str[n] == ' ' )
       
   175                 {
       
   176                 numSpaces++;
       
   177                 }
       
   178         else if( TChar(str[n]).IsSpace() )
       
   179             {
       
   180             if (indexOfFirstNonRegularSpace==-1)
       
   181                 {
       
   182                 indexOfFirstNonRegularSpace = n;
       
   183                 }
       
   184             numSpaces++;
       
   185             if ( f->wordSpacing() == 0 || style.padding() == 0 )
       
   186                 break;
       
   187             }
       
   188         }
       
   189 
       
   190     CFont::TMeasureTextInput input;
       
   191     input.iCharJustExcess = str.Length() * f->letterSpacing();
       
   192     input.iCharJustNum = str.Length();
       
   193     input.iWordJustExcess = numSpaces * f->wordSpacing();
       
   194     input.iWordJustNum = numSpaces;
       
   195     if (maxWidth>0)
       
   196         input.iMaxAdvance = maxWidth;
       
   197     CFont::TMeasureTextOutput output;
       
   198     //input.iMaxAdvance = aMaxAdvance;
       
   199 
       
   200     // see if we need a temporary buffer
       
   201     if( indexOfFirstNonRegularSpace > -1 || f->isSmallCaps() ){
       
   202         HBufC* text = str.Alloc();
       
   203         // don't bother to reverse order for right-to-left, assume the length will be the same
       
   204         if (text){
       
   205             TPtr newStr(text->Des());
       
   206             if ( f->isSmallCaps() )
       
   207                 {
       
   208                 // proper small caps implementation would use smaller font, but that get complicated
       
   209                 // just upper case for now
       
   210                 newStr.UpperCase();
       
   211                 }
       
   212             // if we have non-regular spaces (nbsp, tab, etc.) we need to make a copy
       
   213             // and replace them with regular spaces. otherwise they show up as boxes.
       
   214             if (indexOfFirstNonRegularSpace > -1)
       
   215                 {
       
   216                 for(; indexOfFirstNonRegularSpace<strLength; ++indexOfFirstNonRegularSpace )
       
   217                     {
       
   218                     if( TChar(newStr[indexOfFirstNonRegularSpace]).IsSpace() )
       
   219                         {
       
   220                         newStr[indexOfFirstNonRegularSpace] = ' ';
       
   221                         }
       
   222                     }
       
   223                 }
       
   224             // FIXME: should use smallcap font, which has smaller font size than the current font
       
   225             TInt w = font.MeasureText(*text,&input,&output);
       
   226             delete text;
       
   227             chars = output.iChars;
       
   228             return w;
       
   229             }
       
   230         }
       
   231     TInt w = font.MeasureText(str,&input,&output);
       
   232     chars = output.iChars;
       
   233     return w;
       
   234 }
       
   235 
       
   236 float Font::floatWidthForComplexText(const TextRun& run, const TextStyle& style) const
       
   237 {
       
   238     int chars;
       
   239     return floatWidthForComplexTextSymbian(this, run, style, -1, chars);
       
   240 }
       
   241 
       
   242 
       
   243 int Font::offsetForPositionForComplexText(const TextRun& run, const TextStyle& style, int x, bool includePartialGlyphs) const
       
   244 {
       
   245     int chars;
       
   246     floatWidthForComplexTextSymbian(this, run, style, x, chars);
       
   247     return chars;
       
   248 }
       
   249 
       
   250 }