2012-07-03 6 views
10

कम हो गया है I TIceTabSet (क्रोम टैब) घटक में कई अपडेट कर रहा हूं। इन परिवर्तनों में से एक पारदर्शिता जोड़ने के लिए है। पाठ से अलग सबकुछ ठीक काम करता है। चूंकि पृष्ठभूमि के अल्फा चैनल कम हो जाते हैं, पाठ अधिक से अधिक धुंधला हो जाता है। यहां एक स्क्रीनशॉट है।ग्लास पृष्ठभूमि पर ड्राइंग टेक्स्ट धुंधला हो जाता है क्योंकि अल्फा

enter image description here

यहाँ कोड है जो टैब खींचता है। इसमें से अधिकांश मूल TIceTabSet कोड है। मैंने टैब को पारदर्शी बनाने के लिए बस कुछ बदलाव जोड़े हैं। उदाहरण स्क्रीनशॉट के लिए भी कोड को थोड़ा बदल दिया गया है। नीचे DrawText कमांड है जहां पाठ कैनवास के लिए खींचा जाता है।

procedure TIceTabSet.InnerDraw(Canvas: TCanvas; TabRect: TRect; Item: TIceTab); 
var 
    graphics : TGPGraphics; 
    Pen: TGPPen; 
    Brush: TGPSolidBrush; 
    path, linePath: TGPGraphicsPath; 
    linGrBrush: TGPLinearGradientBrush; 
    font: TGPFont; 
    solidBrush: TGPSolidBrush; 
    rectF: TGPRectF; 
    stringFormat: TGPStringFormat; 
    DC: HDC; 
    marginRight: integer; 
    iconY, iconX: integer; 
    textStart: Extended; 
    startColor, EndColor, textColor, borderColor: cardinal; 
    borderWidth: Integer; 
    TabProperties: TIceTabProperties; 
    Alpha: Byte; 
begin 
    DC := Canvas.Handle; 

    TabProperties := GetTabProperties(Item); 

    Alpha := Item.Index * 50; 

    startColor := MakeGDIPColor(TabProperties.TabStyle.StartColor, Alpha);// TabProperties.TabStyle.Alpha); 
    endColor := MakeGDIPColor(TabProperties.TabStyle.StopColor, Alpha); //TabProperties.TabStyle.Alpha); 
    textColor := MakeGDIPColor(TabProperties.Font.Color, 255); //TabProperties.TabStyle.Alpha); 
    borderColor := MakeGDIPColor(TabProperties.BorderColor, TabProperties.TabStyle.Alpha); 
    borderWidth := TabProperties.BorderWidth; 

    graphics := TGPGraphics.Create(DC); 
    Brush := TGPSolidBrush.Create(borderColor); 
    Pen:= TGPPen.Create(borderColor); 
    Font := GetGDIPFont(Canvas, FTabActive.Font); //TabProperties.Font); 
    try 
    graphics.SetSmoothingMode(SmoothingModeHighQuality); 

    pen.SetWidth(borderWidth); 

    path := TGPGraphicsPath.Create(); 
    try 
     path.AddBezier(TabRect.Left, TabRect.Bottom, TabRect.Left + FTabShape.LeftEdgeWidth/2, TabRect.Bottom, TabRect.Left + FTabShape.LeftEdgeWidth/2, TabRect.Top, TabRect.Left + FTabShape.LeftEdgeWidth, TabRect.Top); 
     path.AddLine(TabRect.Left + FTabShape.LeftEdgeWidth, TabRect.Top, TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top); 
     path.AddBezier(TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top, TabRect.Right - FTabShape.RightEdgeWidth/2, TabRect.Top, TabRect.Right - FTabShape.RightEdgeWidth/2, TabRect.Bottom, TabRect.Right, TabRect.Bottom); 

     linePath := TGPGraphicsPath.Create; 
     try 
     linePath.AddPath(path, false); 
     path.AddLine(TabRect.Right, TabRect.Bottom, TabRect.Left, TabRect.Bottom); 

     linGrBrush := TGPLinearGradientBrush.Create(
      MakePoint(0, TabRect.Top), 
      MakePoint(0, TabRect.Bottom), 
      startColor, 
      endColor); 
     try 
      graphics.DrawPath(pen, linePath); 

      graphics.FillPath(linGrBrush, path); 
     finally 
      linGrBrush.Free; 
     end; 
     finally 
     linePath.Free; 
     end; 
    finally 
     path.Free; 
    end; 

    marginRight := 0; 

    if TabDisplaysCloseButton(Item) then 
    begin 
     if (HighLightTabClose = Item) and 
     (FTabCloseButton.ShowCircle) then 
     begin 
     pen.SetWidth(1); 

     pen.SetColor(MakeGDIPColor(FTabCloseButton.CrossColorHotTrack, 255)); 
     brush.SetColor(MakeGDIPColor(FTabCloseButton.CircleColorHotTrack, 255)); 

     graphics.FillEllipse(brush, TabRect.Right - FTabShape.RightEdgeWidth - 7 - 2, 
            TabRect.Top + ((TabRect.Bottom - TabRect.Top - 7) div 2) - 3, 
            (TabRect.Right - FTabShape.RightEdgeWidth) - (TabRect.Right - FTabShape.RightEdgeWidth - 7) + 6, 
            (TabRect.Top + ((TabRect.Bottom - TabRect.Top + 7) div 2)) - (TabRect.Top + ((TabRect.Bottom - TabRect.Top - 7) div 2)) + 6); 

     graphics.DrawLine(pen, TabRect.Right - FTabShape.RightEdgeWidth - 5, TabRect.Top + ((TabRect.Bottom - TabRect.Top - 5) div 2), 
           TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top + ((TabRect.Bottom - TabRect.Top + 5) div 2)); 

     graphics.DrawLine(pen, TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top + ((TabRect.Bottom - TabRect.Top - 5) div 2), 
           TabRect.Right - FTabShape.RightEdgeWidth - 5, TabRect.Top + ((TabRect.Bottom - TabRect.Top + 5) div 2)); 
     end 
     else 
     begin 
     pen.SetWidth(2); 

     if HighlightTabClose = Item then 
      pen.SetColor(MakeGDIPColor(FTabCloseButton.CrossColorHotTrack, 255)) 
     else 
      pen.SetColor(MakeGDIPColor(FTabCloseButton.CrossColorNormal, 255)); 

     graphics.DrawLine(pen, TabRect.Right - FTabShape.RightEdgeWidth - 7, TabRect.Top + ((TabRect.Bottom - TabRect.Top - 7) div 2), 
           TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top + ((TabRect.Bottom - TabRect.Top + 7) div 2)); 

     graphics.DrawLine(pen, TabRect.Right - FTabShape.RightEdgeWidth, TabRect.Top + ((TabRect.Bottom - TabRect.Top - 7) div 2), 
           TabRect.Right - FTabShape.RightEdgeWidth - 7, TabRect.Top + ((TabRect.Bottom - TabRect.Top + 7) div 2)); 
     end; 

     marginRight := 10; 
    end; 

    solidBrush:= TGPSolidBrush.Create(MakeGDIPColor(textColor, 255)); 

    stringFormat:= TGPStringFormat.Create; 
    stringFormat.SetAlignment(StringAlignmentNear); 
    stringFormat.SetLineAlignment(StringAlignmentCenter); 
    stringFormat.SetTrimming(StringTrimmingEllipsisCharacter); 
    stringFormat.SetFormatFlags(StringFormatFlagsNoWrap); 

    SelectClipRgn(Canvas.Handle, 0); 
    textStart := TabRect.Left + FTabShape.LeftEdgeWidth; 
    iconX := 0; 
    iconY := 0; 

    if Assigned(Images) and (Item.ImageIndex <> -1) then 
    begin 
     iconY := TabRect.Top + ((TabRect.Bottom - TabRect.Top - Images.Height) div 2); 
     iconX := Round(textStart); 
     textStart := textStart + Images.Width + 4; 
    end; 

    rectF := MakeRect(textStart, TabRect.Top, TabRect.Right - textStart - FTabShape.RightEdgeWidth - marginRight, 
     TabRect.Bottom - TabRect.Top); 

    // ****** Text is drawn here ******* 
    if rectF.Width > 10 then 
     graphics.DrawString(format('Alpha: %d', [Alpha]), -1, font, rectF, stringFormat, solidBrush); 
    // ********************************* 

    finally 
    font.Free; 
    solidBrush.Free; 
    Pen.Free; 
    graphics.Free; 
    end; 

    if Assigned(Images) and 
    (Item.ImageIndex <> -1) then 
    Images.Draw(Canvas, iconX, iconY, Item.ImageIndex, true); 
end; 

आप पूर्ण स्रोत here डाउनलोड कर सकते हैं। कृपया ध्यान रखें कि यह एक काम प्रगति पर है। स्रोत पूर्ण होने पर मूल लेखक को वापस सबमिट किया जाएगा।

अद्यतन 1

रूप TLama निश्चित रूप से सुझाव दिया कोड बदलने में मदद करता है, लेकिन यह पूरी तरह से समस्या ठीक नहीं होती। यहाँ कैसे पाठ अब दिखाई देता है:

enter image description here

... यहाँ कैसे गूगल क्रोम दिखाई देता है:

enter image description here

अद्यतन 2

यह इस प्रकार से TextRenderingHintSingleBitPerPixelGridFit साथ दिखाई देता है ।

enter image description here

मैं सभी विकल्प की कोशिश की है और TextRenderingHintAntiAlias ​​ सबसे अच्छा परिणाम देता है।

+0

बस एक कोड के बाकी के बारे में कुछ संकेत (मुझे पता है कि अपने काम अभी भी चल रहा है), लेकिन ऐसा लगता है कि आप अपनी ड्राइंग प्रक्रिया में मिश्रित फ़ॉन्ट गुण (मुझे लगता है कि आप इसके बारे में जानते हैं)। 'TIceTabProperties.FFont.OnChange' ईवेंट हैंडलर को लागू करना भी न भूलें, जहां 'फ़ॉन्ट' संपत्ति परिवर्तन को प्रतिबिंबित करने के लिए 'FIceTabSet'' को अमान्य करें। और समूहों में विधियों और गुणों के प्रारूपण और क्रम को रखने की कोशिश करें, मेरा मतलब है कि सेटर्स, संदेश हैंडलर और गुण स्पष्ट रूप से अलग समूहों में देखने के लिए सर्वोत्तम हैं। – TLama

+0

@TLama: टिप्पणी के लिए धन्यवाद। मैं वर्तमान में सबकुछ काम करने की कोशिश कर रहा हूं, फिर मैं मौजूदा कोड को साफ करने जा रहा हूं (जो कि दो साल से अधिक पुराना है और काफी ध्यान देने की जरूरत है)। – norgepaul

+0

क्या आपने ['TextRenderingHintSingleBitPerPixelGridFit'] (http://msdn.microsoft.com/en-us/library/ms534404%28v=vs.85%29.aspx) मोड की कोशिश की है? – TLama

उत्तर

13

जैसा कि इयान बॉयड ने How to draw ClearType text on Aero glass ? के बारे में अपनी अच्छी पोस्ट में सुझाव दिया है कि जब आप ग्लास की शीट पर टेक्स्ट प्रस्तुत कर रहे हों तो आपको एंटीअलाइजिंग लागू करनी चाहिए।

if rectF.Width > 10 then 
begin 
    if (GetParentForm.GlassFrame.Enabled) and (GetParentForm.GlassFrame.SheetOfGlass) then 
    graphics.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit); 
    graphics.DrawString(Item.DisplayCaption, -1, font, rectF, stringFormat, solidBrush); 
end; 

आपकी समस्या को अनुकरण करने के लिए यह निम्न कोड की तरह एक 3 अलग अलग तरीकों से करता है, सिर्फ एयरो ग्लास की शीट पर पाठ रेंडर करने के लिए काफी है: तो आपकी समस्या को ठीक करने के लिए, अपने कोड इस तरह से संशोधित करने के लिए प्रयास करें:

uses 
    GDIPAPI, GDIPOBJ; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    Font.Color := clWhite; 
    GlassFrame.SheetOfGlass := True; 
    GlassFrame.Enabled := True; 
end; 

procedure TForm1.FormPaint(Sender: TObject); 
var 
    S: WideString; 
    GPFont: TGPFont; 
    GPGraphics: TGPGraphics; 
    GPSolidBrush: TGPSolidBrush; 
    GPGraphicsPath: TGPGraphicsPath; 
begin 
    S := 'This is a sample text rendered on the sheet of Aero glass!'; 
    GPFont := TGPFont.Create(Canvas.Handle, Font.Handle); 
    GPSolidBrush := TGPSolidBrush.Create(MakeColor(GetRValue(Font.Color), 
    GetGValue(Font.Color), GetBValue(Font.Color))); 
    GPGraphicsPath := TGPGraphicsPath.Create; 
    GPGraphicsPath.AddString(S, Length(S), TGPFontFamily.Create(Font.Name), 
    GPFont.GetStyle, GPFont.GetSize, MakePoint(20.0, 60.0), nil); 
    try 
    GPGraphics := TGPGraphics.Create(Canvas.Handle); 
    try 
     GPGraphics.SetSmoothingMode(SmoothingModeAntiAlias); 
     GPGraphics.FillPath(GPSolidBrush, GPGraphicsPath); 
     GPGraphics.DrawString(S, Length(S), GPFont, MakePoint(20.0, 20.0), 
     nil, GPSolidBrush); 
     GPGraphics.SetTextRenderingHint(
     TextRenderingHintSingleBitPerPixelGridFit); 
     GPGraphics.DrawString(S, Length(S), GPFont, MakePoint(20.0, 40.0), 
     nil, GPSolidBrush); 
    finally 
     GPGraphics.Free; 
    end; 
    finally 
    GPFont.Free; 
    GPSolidBrush.Free; 
    GPGraphicsPath.Free; 
    end; 
end; 

और यह निम्न छवि जहां के लिए परिणाम:

  1. पहले पाठ पाठ एंटीलायज़िंग़ बिना DrawString समारोह द्वारा प्रस्तुत किया गया है सक्षम
  2. 01,235,
  3. दूसरा एक SmoothingModeAntiAlias शैली
करने के लिए सेट समरेखण मोड के साथ पाठ एंटीलायज़िंग़ साथ DrawString समारोह सक्रिय है, TextRenderingHintSingleBitPerPixelGridFit मोड
  • तीसरा रास्ता भरने से प्रस्तुत किया गया है करने के लिए कॉन्फ़िगर द्वारा प्रस्तुत किया गया है this article से प्रेरित,

    enter image description here

  • +0

    आपके स्क्रीनशॉट में टेक्स्ट अच्छा दिखता है। समस्या यह प्रतीत होती है कि जब एक पारदर्शी पृष्ठभूमि पर पाठ खींचा जाता है जो स्वयं एरो ग्लास पर खींचा जाता है तो यह गलत दिखने लगता है। जैसे आपकी दूसरी लाइन मेरे लिए सबसे अच्छी लगती है। जब मैं एक पारदर्शी पृष्ठभूमि पर TextRenderingHintSingleBitPerPixelGridFit का उपयोग करता हूं तो यह हमेशा सफेद रंग में खींचता है, इससे कोई फर्क नहीं पड़ता कि मैं किस रंग को फ़ॉन्ट बदलता हूं। अद्यतन में छवि देखें 2. – norgepaul

    +0

    मैंने यह जवाब स्वीकार कर लिया है हालांकि यह ग्लास पर सीधे नहीं आते समय 100% काम नहीं करता है। अगर मुझे समस्या आती है तो मैं यहां समाधान पोस्ट करूंगा। – norgepaul

    5

    वैकल्पिक रूप से, आप थीम एपीआई (Vista और बाद में) के साथ चित्र बनाने का प्रयास कर सकते हैं। विभिन्न छाया/सीमा/चमक सेटिंग्स के साथ बजाना, पठनीय पाठ के साथ आना संभव हो सकता है।


    enter image description here

    कोड (XE2): कांच की शीट पर कुछ परीक्षण

    procedure TForm1.FormPaint(Sender: TObject); 
    var 
        R: TRect; 
        ThemeData: HTHEME; 
        Opts: TDTTOpts; 
    begin 
        R := Rect(10, 10, 150, 30); 
        vcl.themes.DrawGlassText(Canvas.Handle, 'DrawGlassText Sample', R, 0, 3, 
         clBlack, TStyleManager.SystemStyle.GetElementDetails(ttsLabel)); 
    
    
        OffsetRect(R, 160, 0); 
        ThemeData := OpenThemeData(Handle, 'textstyle'); 
    
        Opts.dwSize := SizeOf(Opts); 
        Opts.crText := ColorToRGB(clBlack); 
        Opts.crShadow := $D0D0B0; 
        Opts.iTextShadowType := TST_SINGLE; 
        Opts.ptShadowOffset := Point(1, 1); 
        Opts.fApplyOverlay := True; 
        Opts.iGlowSize := 3; 
        Opts.dwFlags := DTT_TEXTCOLOR or DTT_SHADOWTYPE or DTT_SHADOWCOLOR 
         or DTT_SHADOWOFFSET or DTT_GLOWSIZE; 
        DrawThemeTextEx(ThemeData, Canvas.Handle, TEXT_LABEL, TS_NORMAL, 
         'DrawThemeTextEx Sample', -1, 0, @R, Opts); 
    
        OffsetRect(R, 180, 0); 
        Opts.crText := ColorToRGB(clBlack); 
        Opts.iGlowSize := 4; 
        Opts.fApplyOverlay := True; 
        Opts.dwFlags := DTT_TEXTCOLOR or DTT_GLOWSIZE; 
        DrawThemeTextEx(ThemeData, Canvas.Handle, TEXT_BODYTITLE, 0, 
         'Another Sample', -1, 0, @R, Opts); 
    
        CloseThemeData(ThemeData); 
    end; 
    
    +0

    +1, मुझे लगता है कि ओपी चमक के बिना पाठ प्रस्तुत करना चाहता है, लेकिन यह भी 'DrawThemeTextEx' फ़ंक्शन के साथ संभव होना चाहिए। – TLama

    +0

    @TLama - यह संभव है, लेकिन कुछ सेटिंग्स के साथ जब आप चमक आकार 0 पर सेट करते हैं, तो टेक्स्ट बस गायब हो जाता है। मैं मानता हूं कि ओपी चमक के बिना पाठ प्रस्तुत करना चाहता है, लेकिन जहां तक ​​मैं देख सकता था, चमक के बिना सभी प्रकार की पृष्ठभूमि के खिलाफ पठनीय पाठ प्राप्त करना वाकई मुश्किल है। –

    +0

    दुर्भाग्य से, टैब पर खींचे जाने पर चमक प्रभाव जगह से बाहर दिखाई देगा। अच्छा विचार हालांकि, धन्यवाद। – norgepaul

    संबंधित मुद्दे