Re: TextSuite will nicht
Erst mal ein großes Danke schön für deine guten erklärungen ;) schleim .. muss aber mal gesagt werden
Zitat:
Zitat:
der Codepage zugewiesen werden kann. Der ablauf ist wie folgt Die Anwendung sendet einen PChar für den SongTitle an BassVis
Delphi-Quellcode:
Die Vis.. vis_BassVis holt sich den SongTitel über
mMediaInfo.Songfile := PChar(StreamFile);
Delphi-Quellcode:
von BassVis
SongName := Pointer(SendMessage(This_Mod^.hWNDParent, WM_WA_IPC, PlaylistPos, IPC_GETPLAYLISTTITLE));
Delphi-Quellcode:
Denke kann anstelle von Widestring auch PWideString verwenden.
if StreamInfo.PlaylistTitle <> nil then
ReturnStr := StreamInfo.PlaylistTitle + chr(0); p := @ReturnStr; Inc(p, 1); Result := longint(p); Und es ist wirklich nötig das in der anwendung schon PWidestring verwendet wird ? Das ist schwirig da es in VB kein Widestring gibt String 10 Bytes Bedeutet dann wohl in VB würde es nicht funktionieren mit Unicode Den CodePage kann ich dann ignorieren? EDIT: Habe nun das problem das TextSuite nicht zu WideString kompatibel ist
Delphi-Quellcode:
text: WideString
tsTextOutA(PChar(text));
tsTextOutA erwartet PChar.. hmm scheint nicht so einfach zu sein in der Suite rumwurschteln bringt nix. ;) gruss Emil |
Re: TextSuite will nicht
Zitat:
tsTextOutA ist die ANSI Variante von tsTextOut. tsTextOutW ist die Wide Variante von tsTextOut. tsTextOutA macht intern nichts anderes als den Text mit der aktuellen CodePage in einen WideString zu verwandeln und damit dann tsTextOutW aufzurufen. tsTextOutW erwartet einen pWideChar. tsTextOutW ist die Funktion die du benötigst um WideStrings ausgeben zu können. Wenn du mit Widestrings arbeitest, dann kannst du die Codepage ignorieren. Allerdings habe ich keine Ahnung ob der Text richtig übergeben, da ich nicht verstehen was du da machst. VB habe ich bisher immer gemieden weswegen ich dir dazu auch nichts sagen kann. Auch kann ich nicht erkennen wo der Text genau herkommt. Und ob das bereits Widestrings sind. Aber wichtig ist, dass diese Kette nicht unterbrochen wird. Man kann WideStrings leider direkt zu einem String zuweisen. Und sei es nur als Paramater einer Funktion. Sobald das gemacht wurde ist der Text kaputt bzw. unmapbare Zeichen erscheinen als Fragezeichen. pWideString: Also pWideString benutze ich persönlich nicht. Kann also dazu nur bedingt was sagen. Denn das ist ein Pointer auf einen WideString wärend pWideChar ein Pointer auf das erste Zeichen ist. Das Ende des Strings ist dann durch ein #$0000 gekennzeichnet. Warum ich das Unterscheide liegt im Wesen der Delphi Strings. Diese haben eine Längenangabe und Referenzzählung vor dem Pointer! Denn du jetzt einen pWideChar als pWideString benutzen würdest, dann würde Dephi versuchen auf diese Informationen zuzugreifen. Die würde aber vermutlich nicht existieren. Entsprechend würde es Fehler geben. Da ich mit der TextSuite aber auch andere Sprachen unterstützen will kann ich so etwas natürlich nicht benutzen. Zitat:
Zum Erfragen eines pChar oder pWideChar anhand eines String oder WideString genügt pChar(String) oder pWideChar(WideString) zu machen. Dabei achtet Delphi selber darauf, dass ein abschließendes #0 vorhanden ist und positioniert den Pointer selbsttätig auf das erste Zeichen. Aber auch da musst du darauf achten, dass der String, wärend der Lebensdauer des Pointers über, vohanden ist. Unter anderem ist das ein Grund warum ich innerhalb der TextSuite die Textbehandlung selber in die Hand genommen habe. Wenn ich die Strings nicht selber freigebe bleibt ein Speicherloch aber so werden sie mir nicht unter dem Allerwertesten weggeschossen. |
Re: TextSuite will nicht
Zitat:
Macht keinen sinn dann WideString wider auf PChar zu casten dann war alles umsonst. Zitat:
Returnstring ist nun mal ein string aber die Rückgabe muss Longint bzw.. der pointer auf den string sein. Mir ist da nix anderes eingefallen. Zitat:
übergebe dann meinen Record @mMediaInfo an BassVis(DLL) die konstanze mMediaInfo.Songfile := PChar(StreamFile); zeigt dann auf den String 'StreamFile' jetzt ist nur die frage ob der Record Typensicher ist und der übergebene WideString auch erhalten bleibt. Wie es dann weitergeht habe ich ja schon beschrieben .. weiter oben. EDIT: Du hast da im OpenGl Forum im Thread von TextSuite den Eintrag!
Delphi-Quellcode:
und erstellst damit Chinesiche schriftzeichen
Font1 := TtsFontCreator.Create('C:\WINDOWS\Fonts\verdana.ttf', 14, [], ffBGRA);
Font2 := TtsFontCreator.Create('C:\WINDOWS\Fonts\bonzai.ttf', 36, [], ffBGRA); Font2.AddPostProcessStep(TtsPostPattern.Create(Pattern, 0, 0)); Font2.AddPostProcessStep(TtsPostBorder.Create(1, tsColor($FF, $FF, $FF, $FF))); Font2.AddPostProcessStep(TtsPostShadow.Create(10, 3, 4, 3, $A0)); Font3 := TtsFontCreator.Create('C:\WINDOWS\Fonts\Cyberbit.ttf', 34, [], ffBGRA); Font3.AddPostProcessStep(TtsPostPattern.Create(Pattern, 0, 0)); Font3.AddPostProcessStep(TtsPostBorder.Create(1, tsColor($00, $00, $00, $FF))); Font3.AddPostProcessStep(TtsPostBorder.Create(1, tsColor($FF, $FF, $FF, $FF))); Font3.AddPostProcessStep(TtsPostShadow.Create(4, 3, 4, 3, $A0)); Font4 := TtsFontCreator.Create('C:\WINDOWS\Fonts\Cyberbit.ttf', 34, [], ffBGRA); Font4.AddPostProcessStep(TtsPostBorder.Create(1, tsColor($00, $00, $00, $FF))); Font4.AddPostProcessStep(TtsPostShadow.Create(3, 0, 2, 2, $80)); gibt es ein Sample ohne SDL das ich mir mal anschauen kann dann weiss ich wenn alles richtig läuft das es mit widestring bei mir auch funktioniert. gruss Emil |
Re: TextSuite will nicht
pWideChar auf pChar casten. Muss gestehen. Keine Ahnung ob Delphi da so schlau ist, weil eigentlich beides nur Pointer sind.
Also das Beispielcode was du da hast ist uralt. ;) Also das sind keine öffentlichen Klassen mehr und von den Funktionen her auch anders. Ein direktes Beispiel habe ich nicht, da ich damit andere Dinge zeigen will. Aber der nachfolgende Code sollte hoffentlich genügen. Du kannst den in das SingleLine rein packen. Das einzig Interessante daran ist cAsia. Das sind aneinander gereihte 16 Bit Hexwerte.
Delphi-Quellcode:
Das Arial Unicode MS ist unter XP Standard nicht mehr enthalten. Entsprechend solltest du ein anderes Font benutzen. Das kann dann natürlich vom Bild her dann abweichen. Aber es sollte in etwas wie das Asia.png aussehen.
const
cAsia = #$9019#$662F#$6A23#$54C1#$4E2D#$570B#$6587#$672C#$70BA#$6E2C#$8A66#$5716#$66F8#$9928#$3002; procedure TMainForm.Init_TextSuite; begin tsInit(...) tsSetParameteri(TS_RENDERER, TS_RENDERER_OPENGL); tsSetParameteri(TS_RENDERER_OPENGL_TEXTURE_SIZE, TS_RENDERER_OPENGL_TEXTURE_SIZE_512); tsSetParameteri(TS_CREATOR, TS_CREATOR_GDI_FACENAME); tsFontCreateCreator('Arial Unicode MS', 52, TS_STYLE_NORMAL, TS_DEFAULT, TS_DEFAULT, @fFont1ID); tsPostAddFillColor3ub(233, 118, 33, TS_CHANNELS_RGB); tsPostAddBorder3f(2.4, 1, 1, 1, 1); tsPostAddShadow4f(0, 3, 3, 0, 0, 0, 0.5); tsFontCreateCreator('Bitstream Cyberbit', 52, TS_STYLE_NORMAL, TS_DEFAULT, TS_DEFAULT, @fFont2ID); tsPostAddFillColor3ub(233, 118, 33, TS_CHANNELS_RGB); tsPostAddShadow4f(0, -1, -1, 1, 1, 1, 1); tsPostAddShadow4f(0, 1, 1, 0, 0, 0, 1); tsPostAddBorder4f(1.8, 1, 0, 0, 0, 0.4); begin procedure TMainForm.FormPaint(Sender: TObject); begin // clear screen and depth buffer glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity; glTranslatef(0, 0, -10); // set align to center tsSetParameteri(TS_ALIGN, TS_ALIGN_CENTER); glPushMatrix; glTranslatef(ClientWidth div 2, 90, 0); tsFontBind(fFont1ID); tsTextOutW(cAsia); glPopMatrix; glPushMatrix; glTranslatef(ClientWidth div 2, 180, 0); tsFontBind(fFont2ID); tsTextOutW(cAsia); glPopMatrix; // Check for Errors CheckError; SwapBuffers(fDC); end; Zu dem Dateinamen:
Delphi-Quellcode:
Ich denke genau da könnte schon das Problem sein. Denn StreamFile ist vermutlich ein String, oder? Und damit sind bereits da die Unicode Zeichen weg. Die gesammten Dateioperationen von Delphi. FindFirst/FindNext, TFileStream basieren leider alle auf Ansi und sind nicht Unicode kompatibel.
mMediaInfo.Songfile := PChar(StreamFile);
Der gefährliche Pointer. Weiß nicht wie die Struktur ist. Wenn möglich gar keinen neuen String erzeugen sondern den Weiterreichen den du bekommst. Weil der ist ja schon gültig und kann erst nach dem Funktionsaufruf gelöscht werden. Wenn man den länger benötigt, dann MUSS davon eine Kopie erstellt werden und diese auch so lange gespeichert werden. Strings in Records sind da okay. Selbst wenn die Records dynamisch via New erstellt wurden und mit Dispose wieder gelöscht werden. Beim Löschen aber entweder die Strings leer setzen oder einen typisierten Pointer disposen, da sonst die Referenzzählung der Stings nicht greift. |
Re: TextSuite will nicht
Liste der Anhänge anzeigen (Anzahl: 1)
Es sieht jetzt folgendermaßen aus
Asiatischer Text wird angezeigt. Habe nur innerhalb vis_bassVis string nach PWideChar geändert. in wie weit der Text nun stimmt keine ahnung. Was aber seltsam ist jetzt gehen alle Fonts nicht mehr nur noch asiatische. Ist das ein bug in TextSuite ? gruss Emil |
Re: TextSuite will nicht
Ich denke nicht, dass es ein Fehler in der Bibliothek ist. ;)
String nach pWideChar ist scheinbar nicht richtig. Denn dann nimmt Delphi anscheinend den Pointer des Strings und castet diesen Stumpf nach pWideChar. Das hat dann zur Folge, dass die Zeichen verschmelzen. Es verschmilzt im übrigen auch das letzte Nullzeichen. Wenn das rein zufällig mit einem nicht Null Zeichen verschmilzt wird das Ende des String vernichtet. Das kann riesige Texte aber auch AccessViolations zur Folge haben. Du musst also zu erst den String auf einen WideString zuweisen und den dann als pWideChar casten. Dann würden zu mindest der aktuellen Ansi Text in richtiges Wide verwandelt. Allerdings denke ich nicht, dass du dann sinnvoll asiatische (bzw alles nicht latin-1) texte sehen würdest, da es zu begin ja schließlich ein Ansi string war. Und weg ist in diesem Fall weg. Da kann dir so keiner helfen. Das würde aktuell dann dem oem_charset entsprechen. Also das was im Windows eingestellt wurde. |
Re: TextSuite will nicht
Zitat:
Bei denen wo es mit dem Font nicht funktioniert muss ich halt die alternative zum BitmapFont anbieten so kann man umschalten zwischen realen Fonts oder BitmapFonts (Da fehlen dann halt ein paar zeichen) Habe leider noch keinen vollständigen BitmapFont für OpenGl gefunden Der den ich benutze ist von NEHE 256x256 gruss Emil |
Re: TextSuite will nicht
Ein vollständiges Bitmapfont wird es nicht geben. Denn Unicode hat Platz für $10FFFF (1.114.112) Zeichen. Es sind aber nicht alle belegt. Das mit Abstand umfangreichste Font was ich kenne ist "Arial Unicode MS" mit 50.377 Zeichen. Was aber noch nicht alle definierten Zeichen abdeckt. Aber da mal eine kleine Rechnung. Textur ist 256x256. Ich denke da sind 16x16 Zeichen enthalten. Machen also 256 Zeichen pro Textur. 50.377 / 256 = 196,8 entspricht 197 Texturen. Bei reinen Alphatexturen wären das fast 13 MB. Wenn das RGBA Textuern sind dann das 4fache.
Delphi unterstützt Unicode. Allerdings basiert die VCL, und alle eigenen Bibliotheken leider auf Ansistrings. Aber bei so etwas wie FindFirst/FindNext kannst du auch direkt zur Windows API greifen. Für FileStreams hat jemand im Delphi-forum eine Unicode kompatible Variante geschrieben. Bzw bietet Delphi einen THandleStream und das passende Handle bekommt man durch CreateFileW. TFileStream arbeitet auch so aber benutzt CreateFileA. Für die VCL gibt es TNT Controls die vollständig Unicode kompatibel sind. Wobei die aber mittlerweile nicht mehr frei sind. Aber ich meine ältere freie Versionen wird man sicher noch finden können. Und damit solltest du problemlos in der Lage sein komplexe unicodekompatible Anwendungen erstellen zu können. Obendrein nicht zu vergessen, dass für den Titel/Album/Interpret ja normal die ID3 Tags da sind und in denen können meines Wissens nach Unicode Texte stecken. Denn auch wenn dir diese Aussage jetzt nicht gefällt und da gehe ich mal stark von aus. Aber ich denke nicht, dass ein neues Delphi an deiner derzeitigen Situation etwas ändern würde. Denn Delphi könnte nicht einfach so String durch WideString ersetzen. Das würde bedeuten, dass der Compiler sein Verhalten (bzw das des Codes) ändert und das geht normal gar nicht. Deswegen musst du selber darauf achten wirklich durchgängig mit WideStrings zu arbeiten. Und ein Bitmapfont mit den passenden Buchstaben wird dir da auch nicht viel nützen, denn wenn du die Informationen nicht hast um welche Unicode Zeichen es sind handelt kannst du nicht darauf zugreifen. Und die TextSuite ist dort nichts anderes als ein dynamischen Bitmapfont + reichlich Möglichkeiten es zu manipulieren bzw. Informationen zu erfragen. Allerdings ist das nur meine Meinung und die Entscheidung liegt letzten Endes natürlich bei dir. |
Re: TextSuite will nicht
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Du weißt doch gar nicht ob in den Dateien ein ID3 Tag enthalten ist außerdem visualisiert BassVis auch direkt von der Soundkarte so dass wenn man einen Titel von einem Video übergibt auch dieser angezeigt wird. Das selbe mit meinen Fernseh-programm wenn ich hier visualisiere(mit Plugin ... vis_BassVis) dann will ich sehen welcher Kanal. Programm usw. gerade läuft. Zitat:
Wenn es ein reines Asiatisches oder Koreanisches System ist und die ihre Songs oder was auch immer in Koreanisch abgelegt haben dann haben sie halt pech gehabt. Mit den FoontBitmap wird in Deutsch auch kein äöü usw.. angezeigt. Muss halt damit leben wenn ich diese dem Systemfont vorziehe. Hab mich noch was schlau gemacht.
Delphi-Quellcode:
function EncodeUTF8(const Source: WideString): string;
var Index, SourceLength, CChar: Cardinal; begin { Convert unicode to UTF-8 } Result := ''; Index := 0; SourceLength := Length(Source); while Index < SourceLength do begin Inc(Index); CChar := Cardinal(Source[Index]); if CChar <= $7F then Result := Result + Source[Index] else if CChar > $7FF then begin Result := Result + Char($E0 or (CChar shr 12)); Result := Result + Char($80 or ((CChar shr 6) and $3F)); Result := Result + Char($80 or (CChar and $3F)); end else begin Result := Result + Char($C0 or (CChar shr 6)); Result := Result + Char($80 or (CChar and $3F)); end; end; end;
Delphi-Quellcode:
function ToUnicodeString(s: pchar): WideString;
var pw1 : array[0..1024] of WideChar; nLen1, nLen2, nLen3 : integer; begin nLen1 := Length(s); nLen2 := length(pw1); nLen3 := MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, s, nLen1, @pw1[0], nLen2); if nLen3 > 0 then begin pw1[nLen3] := chr(0); Result := WideString(pw1); end else Result := ''; end;
Delphi-Quellcode:
Das funktioniert denke es liegt mit daran das du kein Koreanisch unterstützt.
function StrToUTF8(s: pchar): string;
var w_str : WideString; begin w_str := ToUnicodeString(s); if w_str <> '' then result := EncodeUTF8(w_str) else result := ''; end;
Delphi-Quellcode:
EDIT:
// Display Song Name
if ShowSong and not pPolygone then begin if PlaylistPos_ <> 0 then PlaylistPos := PlaylistPos_ else PlaylistPos := SendMessage(This_Mod^.hWNDParent, WM_USER, 0, IPC_GETLISTPOS); SongName_ := Pointer(SendMessage(This_Mod^.hWNDParent, WM_WA_IPC, PlaylistPos, IPC_GETPLAYLISTTITLE)); if Strlen(SongName_) > cardinal(fMaxSongLen) then SongName_ := PChar(Ansimidstr(SongName ,1, fMaxSongLen-5) + '..'); SongName := PChar(StrToUTF8(SongName_)); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); // Zeige Playstatus status case PlayState of 0: glPrintXY(fSongLeft, PlaystateYPos, PChar('Stopped'), fLargeFontID, TS_ALIGN_LEFT); 1: glPrintXY(fSongLeft, PlaystateYPos, SongName, fLargeFontID, TS_ALIGN_LEFT); 3: glPrintXY(fSongLeft, PlaystateYPos, PChar('Paused'), fLargeFontID, TS_ALIGN_LEFT); end; if songpos_ <> 0 then songpos := songpos_ else songpos := SendMessage(Module1.hWNDParent, WM_WA_IPC, 0, IPC_GETOUTPUTTIME); strSongpos := GetSongPosStr(songpos); SongLength := SendMessage(This_Mod^.hWNDParent, WM_USER, 1, IPC_GETOUTPUTTIME); strSongLength := GetSongPosStr(1000* SongLength); if PlayState = 0 then glPrintXY(fTimeLeft, PlaystateYPos, PChar('00:00:00 \ 00:00:00'), fLargeFontID, TS_ALIGN_LEFT) else glPrintXY(fTimeLeft, PlaystateYPos, PChar(strSongpos + ' \ ' + strSongLength), fLargeFontID, TS_ALIGN_LEFT) end; Das ist garantiert ein Bug in TextSuite ;) Mein Plugin stürzt ab wenn dieser Font gewählt wird... "Segoe Print" EDIT2: Hmmm irgendwas scheint bei der function EncodeUTF8 auch nicht zu stimmen jetzt werden mit die umlaute "äöü" nicht mehr angezeigt.. na ja muss mal schaun. ;) gruss Emil |
Re: TextSuite will nicht
Die Bibliothek unterstützt UCS-2. Das heißt alle Zeichen die einen Wert zwischen $0000 und $FFFF haben. $FFFF natürlich auch. $0000 kennzeichnet ein Stringende. Und dann natürlich nur die Zeichen die in dem Font enthalten sind. Woher soll ich die sonst auch herbekommen. CJK (Chinesich/Japanisch/Koreanisch) belegen einen ziemlich großen Bereich. Aber der ist trotzdem noch locker unter $FFFF. Und wie du an meinem Bild aus einem der letzen Posts sehen kann unterstüzte ich diesen Bereich.
Ja die hochgeladenen Version enthält mit Sicherheit noch Fehler. Ich habe auch nie gesagt, dass sie fehlerfrei ist. Das wäre nicht nur naiv sondern auch vermessen wenn nicht sogar dumm. Nichts ist absolut fehlerfrei! Ich habe nur gesagt, dass die Fehler die du da hast nicht an der Bibliothek liegen sondern an den Daten die ich bekomme. Die Version der Bibliothek ist im übrigen auch noch keine richtig freigegebene Version. Allerdings kommt sie dem sehr sehr nahe. Ich will nur im Zuge der Hilfe auch noch durch den Code gehen und schauen ob alle Fehlercode richtig sind. Und da ist mir schon so das ein oder andere aufgefallen was problematisch werden könnte. UTF-8 und Umlaute: ÄÖÜ liegen überhalb des Zeichenwertes 127 und entsprechend werden sie von UTF-8 in 2 Byte zerlegt. Wenn du deinen UFT-8 String nun als normalen String betrachtest wird da logischerweise kein ÄÖÜ enthalten sein. Ob das richtig ist was du da hast weiß ich nicht. Habe ich nicht getestet. Um dir auch mal zu demonstrieren, dass es unter Umständen vielleicht doch ein bisschen funktionieren könnte und nicht alles verbugt ist... habe ich extra für dich eine Anwendung gemacht. Inklusive Fontauswahl und einstellbarer Größe. Sie ließt eine UFT-8 Datei ein und gibt sie aus. CJK befindet sich weiter unten in der Datei. Dafür kann man ja scrollen. Probleme: Ich habe die Fonts nicht gefiltert. .fon können nicht dargestellt werden und deswegen sind einige Fonts einfach leer. Bei den Fonts mit dem @ liegen CJK Zeichen auf der Seite. Bei der Version ohne @ ist dies aber nicht so. Das ist scheinbar eine Eigenart von Windows. Keine Ahnung wieso. Und Teilweise ist das Defaultchar etwas komisch. Nicht sichtbar oder viel zu breit. Segeo Print: Ich habe von diesem Font eine Version im Internet gefunden. Das Font ist ca 170kb groß. Ist das richtig? Ich habe die Anwendung auch mal bewusst mit dem Quellen von meinem Server übersetzt und nicht mit den aktuellen Entwicklungsversionen. Falls du damit trotzdem noch Probleme haben solltest, dann schick mir das Font bitte mal, dann schaue ich es mir im Debugger mal an. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz