Casa
Top.Mail.Ru Yandeks.Metrika
Fórum: "Outros";
Arquivo atual: 2017.01.15;
Download: [xml.tar.bz2];

Para baixo

TCanvas. Exibir texto com letras multicoloridas. Encontre agências semelhantes


K-1000 ©   (2016-02-22 16:48) [0]

Objetivo: Imprimir o texto na tela, onde cada letra é pintada em sua própria cor.

Conjurou (junto com o Google) o seguinte código:

função CalcTextExtent (DCHandle: inteiro; Texto: string): TSize; var CharFSize: TABCFloat; começar Result.cx:=0; Result.cy:=0; se Text = "" então sair GetTextExtentPoint32 (DCHandle, PChar (texto), comprimento (texto), resultado); GetCharABCWidthsFloat (DCHandle, Ord (Texto [Comprimento (Texto)]), Ord (Texto [Comprimento (Texto)]), C harFSize); se CharFSize.abcfC <0, então Result.cx:=Result.cx+Trunc(Abs(CharFSize.abcfC)); fim; função CalcTextWidth (DCHandle: inteiro; Texto: string): inteiro; começar Resultado: = CalcTextExtent (DCHandle, Text) .cx; fim; função DrawMulticoloredText (DC: HDC; X, Y: LongInt; const Texto: String; Cores: matriz de LongWord): Boolean; var i: LongInt; Carta: String; LetterWidth: LongWord; começar Resultado: = Falso; if (Length (Text) <> Length (Colors)) então Sair; SetBkMode (DC, TRANSPARENTE); para i: = 1 em Comprimento (texto) faça começar Carta: = Texto [i]; LetterWidth: = CalcTextWidth (DC, Letter); Inc (X, LetterWidth); SetTextColor (DC, cores [i - 1]); se não for TextOut (DC, X, Y, PChar (Letter), Length (Letter)), então Exit; fim; Resultado: = Verdadeiro; fim;

Использование:

DrawMulticoloredText (DC, 300, 300, "QisW", [COLOR_BLUE, COLOR_GREEN, COLOR_RED, COLOR_WHITE]);

Fonte: "Arial Black", 20.
Como resultado, as letras "dançam" ou "em uma pilha".

Onde o cachorro está enterrado?



Kerk ©   (2016-02-22 16:50) [1]

Mostre uma foto de alguma coisa. O que significa dançar ou em grupo?



K-1000 ©   (2016-02-22 16:55) [2]


> Kerk © (22.02.16 16: 50) [1]
>
> Mostre a foto. O que significa dançar ou em uma pilha?


[URL=http://radikal.ru/big/60b29428fd344d98b1d55826d25b504a][IMG]http://s017.radikal.ru/i405/1602/57/f50ed0482e39.png[/IMG][/URL]



K-1000 ©   (2016-02-22 16:56) [3]

* Woops.

http://s017.radikal.ru/i405/1602/57/f50ed0482e39.png



Dimka Maslov ©   (2016-02-22 17:06) [4]

E o que Canvas.TextWidth, Canvas.TextOut, Canvas.Brush já cancelou?



K-1000 ©   (2016-02-22 17:18) [5]


> Dimka Maslov © (22.02.16 17: 06) [4]
>
> E o Canvas.TextWidth, Canvas.TextOut, Canvas.Brush já
> cancelado?
>


Aconteceu que o projeto sem VCL.



Kilkennycat ©   (2016-02-22 17:27) [6]

Ele resolveu um problema semelhante há muito tempo (apenas não pintou, mas simplesmente desenhou-o literalmente) e chegou à conclusão de que é muito difícil criar uma fonte monoespaçada, já que você precisa analisar os vetores de cada letra. caso contrário, será feio - distância demais.



Kilkennycat ©   (2016-02-22 17:33) [7]

mas, em geral, a tarefa é simples. não há delphi em mãos, mas será algo como isto:

em um loop para cada letra:
DrawText (winapi) com a bandeira DT_CALCRECT calcula a largura da letra
Adicione a largura calculada à posição atual.
definir a cor do rígido
DrawText (winapi) sem o sinalizador DT_CALCRECT desenha uma letra da posição atual



Eraser ©   (2016-02-23 03:27) [8]


> Kilkennycat © (22.02.16 17: 27) [6]


> o que não é para uma fonte monoespaçada é muito difícil de fazer

de alguma forma, houve uma ideia de fazer uma seleção de parte dos nomes dos elementos no TListView semelhante à maneira como isso foi feito na pesquisa interna do explorer. , coloque-o em uma gaveta longa, para que também seja interessante procurar, com certeza existe uma solução simples.



Pavia ©   (2016-02-23 12:12) [9]

Tudo é mais simples ao exibir o texto que o próprio Windows substitui pen.pos.
Use o moveto antes do loop e o DrawText no loop.



Kilkennycat ©   (2016-02-23 14:29) [10]


> Tudo é mais simples ao exibir texto O próprio Windows substitui o pen.pos.

com saída letra por letra, também será bonito para um monoespaçado. para a colocação usual de parte de uma letra sob outra (por exemplo Wj ) não será. ficará assim: W j



Pavia ©   (2016-02-23 15:19) [11]

http://s7.postimg.org/pi6722n9n/image.png

E o que estou fazendo de errado desde que WJ e J subiram sob W?
Aqui está uma conclusão monoespaçada de como tornar mais difícil fazer no editor Delphi

procedimento MyTextOut (str: String; Colors: array of LongWord); var i: Inteiro; j: Inteiro; DC: HDC; PenPos: TPoint; começar Form1.PaintBox1.Canvas.MoveTo (20,20); DC: = Form1.PaintBox1.Canvas.Handle; j: = 0; para i: = 1 em Comprimento (Str) faça começar SetTextColor (DC, Colors [J mod Length (Colors)]); Windows.GetCurrentPositionEx (DC, @PenPos); Form1.PaintBox1.Canvas.TextOut (PenPos.X, PenPos.Y, str [i]); Inc (j); fim; fim; procedimento TForm1.Button1Click (Sender: TObject); começar Form1.PaintBox1.Font.Size: = 23; MyTextOut ("wjklmi"); [ClBLUE, ClGREEN, ClRED, clFuchsia]); fim;



Kilkennycat ©   (2016-02-23 15:24) [12]


> Pavia © (23.02.16 15: 19) [11]

hmm ... sim.
mas eu não subi. pode ser alterado agora na conclusão. Eu fiz vin98. e, como resultado, ele fez um monoespaço para remover as omissões feias extras.



Eraser ©   (2016-02-23 18:36) [13]


> Pavia © (23.02.16 15: 19) [11]

e qual SO e versão IDE e fonte?

https://dl.dropboxusercontent.com/u/26403307/2016-02-23_18-32-58.png

testado no Windows 10, delphi 10 seattle.



Eraser ©   (2016-02-23 18:49) [14]


> Borracha © (23.02.16 18: 36) [13]

instalação ajudou
Form1.PaintBox1.Canvas.Brush.Style: = bsClear;
antes da conclusão.



Pavia ©   (2016-02-23 19:37) [15]

Sim Esqueci que o PainBox usa Form1.PaintBox1.Canvas.Brush.Color a partir de um componente inferior (geralmente um formulário).
E o TextOut usa essa cor como plano de fundo, para sombreamento.

OS Win 10.
IDE D7. Os mais antigos precisam ser verificados, tanto quanto me lembro, a largura foi usada não para cada caractere, mas para "W", de modo que o código parecia um monoespaçado.
Para sistemas operacionais mais antigos, é preciso também procurar.



Eraser ©   (2016-02-23 21:20) [16]


> Pavia © (23.02.16 19: 37) [15]

perceber isso
https://dl.dropboxusercontent.com/u/26403307/2016-02-23_21-15-33.png

ali, a presença de várias linhas estraga toda a imagem; para desenhar, você precisa usar DrawText / DrawTextEx, que tropeça, após a entrada de caracteres, sobre essa "multilinearidade".



Pavia ©   (2016-02-24 00:28) [17]

Sim por favor
Todos os erros no código abaixo são recursos declarados. ;-)

Tome RichEdit1 com estilo
RichEdit1.BorderStyle: = bsNone;

tipo TSegment = registro Início, Comprimento: Inteiro; fim; var LastSelectSegment: TSegment; procedimento RhichEditBackColor (RichEdit: TRichEdit; cor: TColor); var Formato: CHARFORMAT2A; começar SendMessage (RichEdit.Handle, EM_HIDESELECTION, 0, LongInt (True)); FillChar (Formato, TamanhoOf (Formato), 0); Format.cbSize: = SizeOf (Format); SendMessage (RichEdit.Handle, EM_GETCHARFORMAT, WPARAM (falso), LPARAM (@Format)); Format.dwEffects: = 0; Format.dwMask: = CFM_BACKCOLOR ou CFM_COLOR ou CFM_FACE; Format.crTextColor: = não Format.crTextColor; Format.crBackColor: = $ FFFFFF xou ColorToRGB (Cor); SendMessage (RichEdit.Handle, EM_SetCHARFORMAT, WPARAM (True), LPARAM (@Format)); fim; var Atualização: Booleano; procedimento TForm1.RichEdit1SelectionChange (Sender: TObject); var RichEdit: TRichEdit; SelectSegment: TSegment; começar RichEdit: = Remetente como TRichEdit; if (FUpdating = False) então começar SelectSegment.Start: = RichEdit.SelStart; SelectSegment.Length: = RichEdit.SelLength; Atualização: = Verdadeiro; TCustomMemo (RichEdit) .SelStart: = LastSelectSegment.Start; TCustomMemo (RichEdit) .SelLength: = LastSelectSegment.Length; RhichEditBackColor (RichEdit, $ FFFFFF xou clWhite); RichEdit.SelStart: = SelectSegment.Start; RichEdit.SelLength: = SelectSegment.Length; Atualização: = Falso; RhichEditBackColor (RichEdit, clYellow); LastSelectSegment: = SelectSegment; fim; fim;



Eraser ©   (2016-02-24 03:18) [18]


> Pavia © (24.02.16 00: 28) [17]

então, para o RichEdit "as perguntas não estão lá, a questão é como organizar você mesmo esse desenho, na foto do explorer [16] ListView, mas acho que não importa qual componente.



Eraser ©   (2016-02-24 03:23) [19]

suspeita-se que não tenha havido sem o gdiplus, nomeadamente https://msdn.microsoft.com/pt-pt/library/windows/desktop/ms534720(v=vs.85).aspx



Eraser ©   (2016-02-24 04:54) [20]

Sim, a caixa realmente abriu através do gdi +. Foi o que aconteceu
https://dl.dropboxusercontent.com/u/26403307/2016-02-24_4-52-50.png

Feito com base em http://landsurvival.com/delphi/METHSystem.Drawing.Graphics.MeasureCharacterRanges.html

procedimento TForm1.PaintBox1Paint (Remetente: TObject); var MyCanvas: TGPGraphics; BrSelect, BrFont: TGPSolidBrush; MyFont: TGPFont; CharRanges: matriz [0..1] de TCharacterRange; StringFormat: TGPStringFormat; sText: string; RctText: TGPRectF; MyRegions: matriz de TGPRegion; I: Inteiro; começar sText: = "Texto longo e longo e longo do teste xxx yyy zzz"; MyCanvas: = TGPGraphics.Create (PaintBox1.Canvas.Handle); tentar MyFont: = TGPFont.Create ("Arial", 14); BrSelect: = TGPSolidBrush.Create (ColorRefToARGB (clYellow)); BrFont: = TGPSolidBrush.Create (ColorRefToARGB (clBlack)); StringFormat: = TGPStringFormat.Create; tentar CharRanges [0] .Primeiro: = 15; CharRanges [0] .Length: = 4; CharRanges [1] .Primeiro: = 25; CharRanges [1] .Length: = 3; StringFormat.SetMeasurableCharacterRanges (2, @CharRanges [0]); RctText.X: = 10; RctText.Y: = 10; RctText.Width: = 150; RctText.Height: = 200; SetLength (MyRegions, Length (CharRanges)); para I: = 0 em comprimento (MyRegions) - 1 do começar MyRegions [I]: = TGPRegion.Create; fim; tentar MyCanvas.MeasureCharacterRanges (sText, sText.Length, MyFont, RctText, StringFormat, 2, MyRegions); para I: = 0 em comprimento (MyRegions) - 1 do começar MyCanvas.FillRegion (BrSelect, MyRegions [I]); fim; MyCanvas.DrawString (sText, sText.Length, MyFont, RctText, StringFormat, BrFont); finalmente para I: = 0 em comprimento (MyRegions) - 1 do começar MyRegions [I] .Free; fim; fim; finalmente StringFormat.Free; BrSelect.Free; BrFont.Free; MyFont.Free; fim; finalmente MyCanvas.Free; fim; fim;



Макс Черных ©   (2016-02-25 02:22) [21]


> com saída letra por letra, também, apenas para um espaço monospacial é bonito
> será. para a colocação usual de partes de uma letra sob outra
> (por exemplo, Wj) não será. ficará assim: W j


Isso é chamado de "pares de kerning". Com uma saída simplificada de caracteres com deslocamento automático do carro, NÃO é executado por definição. Na tela, a diferença com a conclusão correta pode ser visível ou talvez não. Depende do tamanho do fone de ouvido e da fonte.

E para deixar tudo bonito como no RichEdit, é correto usar a função GetCharacterPlacement, que é antiga como um mamute. Ela então apenas uma chamada calcula corretamente todas as posições das letras.



Kerk ©   (2016-02-25 11:38) [22]

https://imgs.xkcd.com/comics/kerning.png



Страницы: 1 filial inteira

Fórum: "Outros";
Arquivo atual: 2017.01.15;
Download: [xml.tar.bz2];

em cima





Memória: 0.65 MB
Hora: 0.086 c
15-1453057828
Quem duvidaria
2016-01-17 22:10
2017.01.15
Aumente a exceção para Application.Run NÃO mostrará a mensagem.


15-1449675538
Rouse_
2015-12-09 18:38
2017.01.15
Promoção de VMProt


15-1435613404
júri
2015-06-30 00:30
2017.01.15
Parabéns pra você! 30 Jun 2015 terça-feira


1-1343276932
Skyle
2012-07-26 08:28
2017.01.15
FloatToTextFmt retorna -922337203685477.5808


15-1456747091
Msguns
2016-02-29 14:58
2017.01.15
Quem somos nós?





afrikaans albanês Arabic armênio azerbaijano basco belarusian Bulgarian catalão Chinês simplificado) Chinês tradicional) croata checo dinamarquês Dutch Inglês estoniano filipino Finnish French
Galego georgiano German grego crioulo haitiano hebraico hindi húngaro islandês Indonesian irlandês Italian Japanese Korean letão lituano macedónio Malay maltês Norwegian
persa polonês Portuguese Romeno Russa sérvio Slovak esloveno Espanhol swahili sueco tailandês turco ucraniano urdu vietnamita galês ídiche bengali bósnio
cebuano esperanto gujarati hausa hmong igbo javanês kannada khmer lao latino maori marata mongol Nepali punjabi somali tâmil telugu yoruba
zulu
Английский francês Alemão Italiano Португальский russo Espanhol