Перейти к содержанию
  • Регистрация
  • 0
web_warp

Canvas FillText: особенности работы

Вопрос

В этой теме я уже задавал вопрос, но, наверное, я просто ошибся разделом. Аккумулирую вопрос:

10.1 Berlin, C++, Win8, FMX. Интересует особенность работы Canvas->FillText(), вот код:

void __fastcall TTabbedForm::StringGrid1DrawColumnCell(TObject *Sender, TCanvas * const Canvas,
		  TColumn * const Column, const TRectF &Bounds, const int Row,
		  const TValue &Value, const TGridDrawStates State)
{
	// код...
	UnicodeString CT = TabbedForm->StringGrid1->Cells[Column->Index][Row];
	Canvas->FillText(Bounds, CT, false, 100,TFillTextFlags() << TFillTextFlag::ftRightToLeft, TTextAlign::taTrailing, TTextAlign::taTrailing);
}

В итоге наблюдаются совсем странные "фишки":

1. Разворот времени, хотя в FillText() текст передаётся правильный.canvas error.png

2. Если текст заканчивается на скобку, то скобка разворачивается и переносится в начало текста.error canvas.png

3. И, если есть и кириллица, и латиница, то текст просто не выводится)) (хотя есть подозрение, что это кавычки виноваты).canvaserror2.png

 

Кто сталкивался? Что делать? Есть альтернативы?

Изменено пользователем web_warp
Расставил картинки под пункты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рекомендуемые сообщения

  • 0

если я правильно понял, вы используете написание текста справа-налево

TFillTextFlag.RightToLeft - этот параметр не нужно указывать, в делфи там ставится []

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 22.10.2016 в 10:41, ZuBy сказал:

TFillTextFlag.RightToLeft - этот параметр не нужно указывать, в делфи там ставится []

Это С++, там на этих костылях весь фундамент держится. Изменение параметра RightToLeft <--> ftRightToLeft никакого эффекта не дают. (

Согласно документации (тык, тык) всё верно, но отрабатывает некорректно до ужаса.

Эти параметры не несут функционального смысла, у меня ничего не меняется:

enum class DECLSPEC_DENUM TFillTextFlag : unsigned int { RightToLeft, ftRightToLeft _DEPRECATED_ATTRIBUTE3("Use TFillTextFlag.RightToLeft")  = 0x0 };
Изменено пользователем web_warp

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Простите меня за мою же глупость. ) Разобрался, с горем-пополам.

Верная строка вот такая:

TabbedForm->StringGrid1->Canvas->FillText(Bounds,TabbedForm->StringGrid1->Cells[Column->Index][Row], false, 100,TFillTextFlags(), TTextAlign::taLeading, TTextAlign::taLeading);

Большинство артефактов удалось устранить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Похожий контент

    • От Павел Блажеев
      Добрый день. Очень нужна Ваша помощь. 
      Мне необходимо сделать координатную сетку в виде точек. При масштабировании панели количество точек должно изменяться . 
      Хочу все это сделать на канве панели. Унаследовал класс и переопределил procedure   Paint; override;
        Tfield = class(TPanel)
            Constructor Create( parent: TFmxObject);
              procedure   Paint; override;
              Procedure   OnMyClick (Sender: TObject);
          end;

      В теле метода я пробовал рисовать. Экспериментировал и столкнулся с такой проблемой. Ничего не отображается. Нет никаких изменений.
      Если я наследую не от Tpanel а от Timage то часть кода работает а часть работает очень криво. Очень хочу разобраться почему .
      {Отображается сразу}
      for a:=1 to 1000 do
            begin
              self.Canvas.Fill.Color:=  TAlphaColors.Crimson;
               self.Canvas.FillEllipse(rect(1,1,10,10),self.AbsoluteOpacity);
               self.Canvas.FillEllipse(rect(round(self.Width-9),round(self.Height-9),round(self.Width), round(self.Height)),self.AbsoluteOpacity);
               self.Canvas.FillEllipse(rect(round(self.Width-9),1,round(self.Width), 9),self.AbsoluteOpacity);
               self.Canvas.FillEllipse(rect(1,round(self.Height-9),10, round(self.Height)),self.AbsoluteOpacity);
            end;
       
      {Отображается только после того как я проскролю Scrollbox на котором лежит панель в крайнее нижнее правое положение}
            self.Canvas.Stroke.Color:=  TAlphaColors.Crimson;
            self.Canvas.Stroke.Thickness:=7;
             Canvas.BeginScene;
            self.Canvas.DrawLine(PointF(20, 20), PointF(100, 50), self.AbsoluteOpacity);
             Canvas.EndScene;
      Подскажите пожалуйста, почему не работает такое с панелью?  Как правильно рисовать на панели? 
      Почему в случае с имейджем все работает так некорректно?  Почему работает только после скрола? 
      Каким способом мне лучше сделать координатную сетку? состоящую из точек как в режиме Design?

       


    • От Mars M
      Рисую текст на TGid'е.
      Вот такой код:
      ........... StrInfo := 'Подключение...'; Canvas.FillText(aInfoRect, StrInfo, False, 1, [TFillTextFlag.RightToLeft], TTextAlign.Trailing, TTextAlign.Center); Текст выводит вот так - ...Подключение
      Проблема я так понял не нова http://fire-monkey.ru/topic/3234-canvas-и-filltext-в-stringgridе-разворот-времени/
      Совет из той темы не помог.
      Как исправить?
    • От Zyablik3000
      Здравствуйте!
      Есть самописный компонент - индикатор загрузки написанныый под VCL с использованием Direct2D.
      TD2DProgressBar = class(TCustomControl) FRenderTarget: ID2D1RenderTarget; FD2DFactory.CreateWicBitmapRenderTarget(FWicBitmap, RenderTargetProp, FRenderTarget); FInteropTarget := FRenderTarget as ID2D1GdiInteropRenderTarget; Вся отрисовка происходит на FRenderTarget.
      Затем беру
      FInteropTarget.GetDC(D2D1_DC_INITIALIZE_MODE_COPY, FRenderDC); и вывожу на поверхность функцией
       
      procedure TD2DProgressBar.UpdateWindow(sourceDC : HDC); var info : TUpdateLayeredWindowInfo; begin ZeroMemory(@info, sizeof(info)); with info do begin cbSize := sizeof(TUpdateLayeredWindowInfo); pptSrc := @FSourcePosition; pptDst := @FWindowPosition; psize := @FWndSize; pblend := @FBlend; dwFlags := ULW_ALPHA; end; info.hdcSrc := SourceDC; if not UpdateLayeredWindowIndirect(handle, @info) then begin RaiseLastOSError(); end end; Но это только под VCL.
      В Firemonkey не нашел способа комбинировать градиенты и/или нарисовать арку градиентом (саму линию арки а не залить сектор) или комбинацией градиентов.
       
      Как вывести этот FRenderTarget на канву Firemonkey-контрола?
      Самая большая проблема в том, что компонент полупрозрачный, и вариант с переливом через Vcl.Graphics.TBitmap и MemoryStream не дает нужного результата.
       
      MS:=TMemoryStream.Create; Blend.BlendOp := AC_SRC_OVER; Blend.BlendFlags := 0; Blend.AlphaFormat := AC_SRC_NO_PREMULT_ALPHA; Blend.SourceConstantAlpha:= 255; // // Уровень прозрачности Res:=Winapi.Windows.AlphaBlend(VCLBitmap.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height, FRenderDC, 0, 0, VCLBitmap.Width, VCLBitmap.Height, Blend); {или эта функция StretchBlt(bm.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height, FRenderDC, 0, 0, VCLBitmap.Width, VCLBitmap.Height, SRCCOPY); } VCLBitmap.SaveToStream(MS); FFMXBitmap.SetSize(TSize.Create(VCLBitmap.Width, VCLBitmap.Height)); FFMXBitmap.LoadFromStream(MS); FreeAndNil(MS);  
      В Blend пробовал разные комбинации BlendOp и AlphaFormat.
      Хелп плизз!
      Во вложении компонент под VCL. ( Может кому пригодится)) )
      D2DProgressbar.zip

    • От Ильдар
      Добрый день, идеология такая:
      - создать битмап, рисовать на нем, не делая его видимым.
      - нашлепать на канву панели подготовленный битмап.
       
      На деле не получается нарисовать линию на битмапе. Т.е после процедуры Draw2 прожимаю процедуру Draw - получаю на панели красный прямоугольник битмапа без нарисованной линии...
      Посоветуйте чего-нибуть, спасибо!
       
      //BITMAP Bm:= TBitmap.Create; bm.Width:= round (Panel.Width/2); bm.Height:= round (Panel.Height/2); bm.Canvas.BeginScene(); bm.Canvas.Clear(TAlphacolorrec.Red); //($FF484848); bm.Canvas.EndScene; procedure TChart.Draw2; var A,B:TPointF; begin A:=TPointF.Create(0,0); B:=TPointF.Create(200, 200); bm.Canvas.BeginScene(); bm.Canvas.DrawLine(A,B,1); bm.Canvas.EndScene; end; procedure TChart.Draw; var A: TPointF; R: TRectF; begin A.X:= Panel.Position.X+3; A.Y:= Panel.Position.Y+3; R:= TRectF.Create(A, bm.Width , bm.Height); panel.Canvas.BeginScene(); Panel.Canvas.DrawBitmap(bm,r,r, 20); panel.Canvas.EndScene; end;  
    • От Julia
      Загружаю через opendialog картинку  формата bmp в image
      Есть переменные с:TColor, c1:Tcolor
      Необходимо  вначале узнать цвет определенного пикселя на загруженной картинке и записать в  c1, а затем изменить цвет определенного пикселя на загруженной картинке на цвет, хранящийся в переменной c.
      Ищу очень давно, но внятного объяснения нигде не нашла(
       
       
    • От Maximus
      Доброго всем времени суток. Хочу снова поднять вопрос про отрисовку линий на канве, обсуждавшейся здесь
      С горизонтальными и вертикальными линиями проблем нет, при смещении на половину от толщины линии всё прекрасно выглядит. Однако при отрисовке линий под различными углами такой финт не проходит: слева VCL, справа FMX

      Линия всё так же размазывается, в итоге визуально утолщается и становится не такой чёткой.
      Как всё же добиться такого же результата как на VCL? Интересует только Windows.
      const OFFSET_LINE = 0.5; ... Image.Bitmap.Canvas.BeginScene; Image.Bitmap.Canvas.Stroke.Kind := TBrushKind.Solid; Image.Bitmap.Canvas.Stroke.Thickness := 1.0; Image.Bitmap.Canvas.DrawLine( PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), PointF(500.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), 1.0); Image.Bitmap.Canvas.DrawLine( PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), PointF(10.0 - OFFSET_LINE, 500.0 - OFFSET_LINE), 1.0); Image.Bitmap.Canvas.DrawLine( PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), PointF(500.0 - OFFSET_LINE, 500.0 - OFFSET_LINE), 1.0); Image.Bitmap.Canvas.EndScene;  
    • От ODmitrijS
      Подскажите алгоритм или готовый пример заливки замкнутой области рисунка произвольной формы определенным цветом?
      Моё решение часто приводит к переполнению стека.
    • От Error
      *** Небольшой обмен опытом ***
      Вижу что вопросы о размере текста довольно частые, поделюсь своими наработками.
      function CalcTextSize(Text: string; Font: TFont; Size: Single = 0): TSizeF;
      Функция для расчета размера прямоугольника, занимаемого однострочным текстом.
      Параметры:
      Text - Текст Font - Шрифт с которым будет выводиться текст Size - если 0, то Font.Size будет использоваться из Font, иначе из данного параметра Исходный код:
      uses System.Types, FMX.Types, FMX.Graphics, FMX.TextLayout, System.Math, System.SysUtils; function CalcTextSize(Text: string; Font: TFont; Size: Single = 0): TSizeF; var TextLayout: TTextLayout; begin TextLayout := TTextLayoutManager.DefaultTextLayout.Create; try TextLayout.BeginUpdate; try TextLayout.Text := Text; TextLayout.MaxSize := TPointF.Create(9999, 9999); TextLayout.Font.Assign(Font); if not SameValue(0, Size) then begin TextLayout.Font.Size := Size; end; TextLayout.WordWrap := False; TextLayout.Trimming := TTextTrimming.None; TextLayout.HorizontalAlign := TTextAlign.Leading; TextLayout.VerticalAlign := TTextAlign.Leading; finally TextLayout.EndUpdate; end; Result.Width := TextLayout.Width; Result.Height := TextLayout.Height; finally TextLayout.Free; end; end;   function FontSizeForBox(Text: string; Font: TFont; Width, Height: Single; MaxFontSize: Single = cMaxFontSize): Integer;
      Функция возвращающая максимально возможный размер шрифта, для текста вписанного в заданный прямоугольник.
      Параметры:
      Text - Текст Font - Шрифт с которым будет выводиться текст Width, Height - Ширина и высота прямоугольника MaxFontSize - Максимально возможный размер шрифта Исходный код:
      uses System.Types, FMX.Types, FMX.Graphics, FMX.TextLayout, System.Math, System.SysUtils; const cMaxFontSize = 512; function FontSizeForBox(Text: string; Font: TFont; Width, Height: Single; MaxFontSize: Single = cMaxFontSize): Integer; var Size, Max, Min, MaxIterations: Integer; Current: TSizeF; begin Max := Trunc(MaxFontSize); Min := 0; MaxIterations := 20; repeat Size := (Max + Min) div 2; Current := CalcTextSize(Text, Font, Size); if ((Abs(Width - Current.Width) < 1) and (Width >= Current.Width)) and ((Abs(Height - Current.Height) < 1) and (Height >= Current.Height)) then break else if (Width < Current.Width) or (Height < Current.Height) then Max := Size else Min := Size; Dec(MaxIterations); until MaxIterations = 0; Result := Size; end; ---
      Также данные функции можно найти в этом юните
    • От Steepe_Hare
      Под Windows 32  приложение собирается и работает отлично, под Android при запуске из RAD-среды сразу говорит: Project project1.apk raised exception class ECanvasException with message 'Handle not allocated' и отказывается работать.
      В чем может быть причина?
    • От web_warp
      В DrawColumnCell провожу зарисовку некоторых строк, необходима подсветка цветом. И тут возникла неожиданная проблема на ровном месте: ячейка, где текстом записано время, почему-то меняет местами время и дату, хотя передаётся в функцию FillText как надо.
      TabbedForm->StringGrid1->Canvas->Fill->Color = background_color; TabbedForm->StringGrid1->Canvas->FillRect(Bounds, 0, 0, AllCorners, 100); TabbedForm->StringGrid1->Canvas->Fill->Color = font_color; TabbedForm->StringGrid1->Canvas->Font->Style << fsBold; TabbedForm->StringGrid1->Canvas->FillText(Bounds,TabbedForm->StringGrid1->Cells[Column->Index][Row], false, 100,TFillTextFlags() << TFillTextFlag::ftRightToLeft, TTextAlign::taTrailing, TTextAlign::taTrailing); Подскажите пожалуйста, как развернуть время обратно?

      Ну и параллельно вопрос: как строку сплошным цветом заливать? Без белых границ?
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...