CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Gdiplus - DrawString, Jak ustawić charset

Gdiplus - DrawString, Jak ustawić charset

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Mironas » środa, 14 sierpnia 2013, 22:08

Jak ustawić 'nietypowy' charset dla rysowania tekstu w Gdiplus?
Poniższy kod rysuje tekst ale ignoruje 'BALTIC_CHARSET'.

KOD cpp:     UKRYJ  
  Image1->Canvas->Font->Charset = BALTIC_CHARSET;
  Gdiplus::Font* font = new Gdiplus::Font (Image1->Canvas->Handle);

  Gdiplus::Bitmap BMP = new Gdiplus::Bitmap (szer, wys, PF);
  Gdiplus::Graphics graf (BMP);

  graf.DrawString((WideString)s, -1, font, point_tekst, &brush);
 
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 446
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 21
Otrzymał podziękowań: 63
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez polymorphism » czwartek, 15 sierpnia 2013, 10:06

Spróbuj zrobić fonta z użyciem struktury LOGFONT.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2187
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 204
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    Windows XPFirefox

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Cyfrowy Baron » czwartek, 15 sierpnia 2013, 10:34

Gdiplus nie ma harsetu ma za to funkcję SetDigitSubstition, która służy do ustawienia języka i sub-języka dla wyświetlanego tekstu. Tyle, że to w zasadzie niczego nie zmienia, gdyż gdiplus dobrze sobie radzi z każdą czcionką, więc ustawianie tego parametru nie ma większego znaczenia. Ciekawi mnie w jakiej sytuacji jest ci to potrzebne.

Przykład zastosowania SetDigitSubstition:
KOD cpp:     UKRYJ  
#pragma option -w-hid
#include <gdiplus.h>
#pragma option -w-hid.

    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        ULONG_PTR gdiplusToken;

#pragma link "gdiplus.lib"

 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

  Gdiplus::RectF layoutRect( 0, 5, Image1->Width, Image1->Height);
  Gdiplus::Font myFont(L"Tahoma", 16);

//  LANGID language = MAKELANGID(LANG_POLISH, SUBLANG_POLISH_POLAND);

  Gdiplus::StringFormat format;
  format.SetAlignment(StringAlignmentCenter);
  format.SetDigitSubstitution(LANG_POLISH, SUBLANG_POLISH_POLAND);

  Gdiplus::SolidBrush redBrush( Gdiplus::Color(255, 255, 0, 0) );


  Gdiplus::Graphics graf (Image1->Canvas->Handle);

  graf.DrawString( L"TEST Przykładowy tekst ", -1, &myFont, layoutRect, &format, &redBrush);


Nie bardzo rozumiem na czym to ma polegać, gdyż zmiana harsetu np. w Memo też niczego w tekście pisanym nie zmienia, gdyż jak wynika z moich obserwacji - system zamiast określonej czcionki podstawia taką, która zawiera znaki podane w tekście.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4727
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 444
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Mironas » czwartek, 15 sierpnia 2013, 11:37

polymorphism napisał(a):Spróbuj zrobić fonta z użyciem struktury LOGFONT.

Nie pomaga. Wcześniej też próbowałem z HFONT i też nic.

Cyfrowy Baron napisał(a):Ciekawi mnie w jakiej sytuacji jest ci to potrzebne.

Ale pamiętasz, że ciekawość to pierwszy stopień do piekła? ;)
Wysyłam starą aplikację (pisaną jeszcze w BCB6) na Łotwę. Okazało się, że domyślne ustawienie Font->Charset (DEFAULT_CHARSET) powoduje, że na ich komputerach (np w Edit, Memo) nie wpisują się poprawnie ich literki:
AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ
aābcčdeēfgģhiījkķlļmnņoprsštuūvzž

Po ręcznej zmianie wszystkich charest-ów na BALTIC_CHARSET Działa poprawnie. Ale w aplikacji wykorzystuję Gdiplus do generowania m.in. grafik z tekstami - i z tego co widzę, tam nadal nie generują się znaki z ich alfabetu. A jak sprawdzę:
KOD cpp:     UKRYJ  
  LOGFONTA LF;
  font->GetLogFontA(&graf, &LF);
  LF.lfCharSet;
 

to LF.lfCharSet ma wartość 238 czyli EASTEUROPE_CHARSET - czyli moje ustawienia systemowe. Dlatego liczę, że u nich będzie to domyślnie BALTIC_CHARSET.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 446
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 21
Otrzymał podziękowań: 63
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Cyfrowy Baron » czwartek, 15 sierpnia 2013, 12:23

Spróbuj tego:

KOD cpp:     UKRYJ  
LANGID language = MAKELANGID(LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA);

  format.SetDigitSubstitution(LANG_RUSSIAN, language);



Tylko, że BCB6 operowało na AnsiString, a XE i nowsze na UnicodeString, więc cokolwiek testujesz w nowszej wersji środowiska będzie działać prawidłowo. U siebie w XE2, żeby wstawić cyrylicę w Memo nie muszę wogóle zmieniać charset, działa na DEFAULT_CHARSET. Jakiego charset'u bym nie ustawił mogę bez problemu wpisywać cyrylicę.

Mironas napisał(a):Po ręcznej zmianie wszystkich charest-ów na BALTIC_CHARSET Działa poprawnie.


Z tego co widzę u siebie to dostępny jest charset = RUSSIAN_CHARSET.

Przejrzałem dokumentację dla GDI+ i nie widzę tam niczego poza SetDigitSubstition co pozwalałoby w jakikolwiek sposób wpływać na opcje językowe czcionki.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4727
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 444
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Mironas » czwartek, 15 sierpnia 2013, 12:53

Cyfrowy Baron napisał(a):format.SetDigitSubstitution(LANG_POLISH, SUBLANG_POLISH_POLAND);

W BCB6 nie mam zdefiniowane SUBLANG_POLISH_POLAND (ani SUBLANG_LATVIAN_LATVIA).
Jednak jak wyżej pisałem mam nadzieję, że pod łotewskim windowsem będzie to poprawnie działało.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 446
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 21
Otrzymał podziękowań: 63
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez polymorphism » czwartek, 15 sierpnia 2013, 13:07

Mironas napisał(a):Nie pomaga. Wcześniej też próbowałem z HFONT i też nic.

Ustawienie DEFAULT_CHARSET powinno załatwić sprawę, ale... Pokaż jak tworzysz tego fonta.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2187
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 204
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    Windows XPFirefox

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Mironas » czwartek, 15 sierpnia 2013, 13:39

polymorphism napisał(a):Pokaż jak tworzysz tego fonta.

Tak na próbę - w ten sposób:
KOD cpp:     UKRYJ  
  Image1->Canvas->Font->Charset = Font->Charset;
  Gdiplus::Graphics graph (Image1->Canvas->Handle);
  Gdiplus::Font* font1 = new Gdiplus::Font (Image1->Canvas->Handle);

  LOGFONTA LF;
  font1->GetLogFontA(&graph, &LF);
  LF.lfCharSet = BALTIC_CHARSET;

  // tworzenie właściwego fonta
  Gdiplus::Font* font2 = new Gdiplus::Font (Image1->Canvas->Handle, &LF);

  // sprawdzenie charset-u
  font2->GetLogFontA(&graph, &LF);
  ShowMessage( LF.lfCharSet );    // zwraca 238 czyli EASTEUROPE_CHARSET
 
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 446
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 21
Otrzymał podziękowań: 63
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez polymorphism » czwartek, 15 sierpnia 2013, 13:55

Wygląda OK. Trudno powiedzieć skąd ten problem.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2187
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 204
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    Windows XPFirefox

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Cyfrowy Baron » czwartek, 15 sierpnia 2013, 14:58

Dzieje się tak chyba dlatego, że jak już Font pobierze uchwyt do LOGFONT to go nie zwalnia i nie pozwala zmienić wartości struktury. Wartość lfCharSet należy więc zmieniać przed wywołaniem funkcji GetLongFont_. Sprawę komplikuje dodatkowo to, że w XE2 działa to tylko ze strukturą LOGFONTW:

Tak zadziała i komunikat pokaże wartość 204:
KOD cpp:     UKRYJ  
  Image1->Canvas->Font->Charset = Font->Charset;
  Gdiplus::Graphics graph (Image1->Canvas->Handle);
  Gdiplus::Font* font1 = new Gdiplus::Font (Image1->Canvas->Handle);

  LOGFONTW LF;
  LF.lfCharSet = RUSSIAN_CHARSET;

  Gdiplus::Font* font2 = new Gdiplus::Font (Image1->Canvas->Handle, &LF);


  // sprawdzenie charset-u
  font2->GetLogFontW(&graph, &LF);
  ShowMessage( LF.lfCharSet );    // zwraca 204 czyli RUSSIAN_CHARSET;
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4727
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 444
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Mironas » czwartek, 15 sierpnia 2013, 16:38

Tak zadziałało - na chwilkę :(
Wystarczyło dodać LF.lfWeight = FW_BOLD; (lub FW_NORMAL lub cokolwiek innego) i znowu się rozjechało:
KOD cpp:     UKRYJ  
  Gdiplus::Graphics graph (Image1->Canvas->Handle);

  LOGFONTW LF;
  LF.lfWeight = FW_BOLD;  // po dodaniu tego
  LF.lfCharSet = RUSSIAN_CHARSET;

  Gdiplus::Font* font2 = new Gdiplus::Font (Image1->Canvas->Handle, &LF);

  // sprawdzenie charset-u
  font2->GetLogFontW(&graph, &LF);
  Form1->Caption = LF.lfCharSet;    // znowu zwraca 238 (EASTEUROPE_CHARSET)
 


Panowie, na razie zawieszam dyskusję. Być może tak jak pisałem na łotewskim windowsie wszystko będzie działało dobrze. Wysłałem program, klient na razie nie zgłasza tego problemu więc szkoda naszego czasu. Jeśli problem jednak się pojawi to odezwę się ponownie.
Dziękuję za zaangażowanie i pozdrawiam.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 446
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 21
Otrzymał podziękowań: 63
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Mironas » piątek, 16 sierpnia 2013, 13:11

Problem wygląda o wiele gorzej i nie dotyczy tylko Gdiplus ale też standardowych komponentów VCL w BCB6. Przykładowo TButton i TLabel wyświetlają tekst zupełnie inaczej. Oba mają ustawiony charset na BALTIC_CHARSET i wstawiony ten sam tekst (alfabet łotewski):
KOD cpp:     UKRYJ  
  Button1->Caption = "AÂBCČDEÇFGĚHIÎJKÍLĎMNŇOPRSĐTUŰVZŢ";
  Label1->Caption = "AÂBCČDEÇFGĚHIÎJKÍLĎMNŇOPRSĐTUŰVZŢ";
 

W efekcie na labelu tekst wyświetla się poprawnie a na buttonie nie (załączam zrzut). Ręce opadają. Nie pozostaje nic innego jak odpuścić sobie klienta i niech czeka na nową wersję programu napisaną w XE.
Ostrzeżenie dla wszystkich: Nie pisać programów w BCB6 dla Łotwy.
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 446
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 21
Otrzymał podziękowań: 63
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez polymorphism » piątek, 16 sierpnia 2013, 13:19

I po to właśnie powstał unikod...

p.s. jesteś pewny, że kodowanie pliku źródłowego jest takie same jak ma system klienta?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2187
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 204
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    Windows XPFirefox

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez Mironas » piątek, 16 sierpnia 2013, 13:37

polymorphism napisał(a):jesteś pewny, że kodowanie pliku źródłowego jest takie same jak ma system klienta?

Nie wiem co masz na myśli. Na Łotwie używają kodowania Windows-1257. Pliki źródłowe (cpp/h) mam normalnie w ANSI. Tylko jakie to ma znaczenie. Znak to znak - konkretna wartość. W kodzie może mi się wyświetlać nieprawidłowo.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 446
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 21
Otrzymał podziękowań: 63
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Gdiplus - DrawString, Jak ustawić charset

Nowy postprzez polymorphism » piątek, 16 sierpnia 2013, 14:16

Jak by to było takie proste, znak-to-znak, to nie miałbyś teraz takich problemów. To "normalnie w ANSI" to jakie konkretnie kodowanie jest? Jak piszesz na polskim windowsie, to "normalne ANSI" z reguły oznacza kodowanie windows-1250 (na łotewskim windowsie pewnie jest to windows-1257), i w takim kodowaniu są wszystkie literały w Twojej aplikacji. Dla polskiego języka są co najmniej trzy kodowania, dlatego wystarczy, że aplikacja będzie miała inne kodowanie niż systemowe, by mieć problem z wyświetlaniem znaków. Dlatego dziś między innymi pisze się aplikacje w unikodzie.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2187
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 204
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    Windows XPFirefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

Użytkownicy przeglądający ten dział: Google [Bot] i 1 gość

cron