amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > word wrap [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- 2 3 [ - Beitrag schreiben - ]

15.08.2009, 22:39 Uhr

AGSzabo
Posts: 1663
Nutzer
hi,

ich suche diesmal tips, hinweise oder vielleicht algo-vorschläge wie man einen word-wrap programmiert, dammit der text in der box am rechten rand der box wortweise umbrochen wird.

ps: ich kenne die diversen Text..(.) funktionen der gfx libr.


damit keiner auf die idee kommt ich würde meine hausaufgaben nicht machen, hier als beweis meine selbst ausgedachte auf-/abrundungs funktion:
code:
; auf oder ab runden, d2 = d0/d1

		divu.w	d1,d0
		move.w	d0,d2
		swap	d0
		lsr	#1,d1
		cmp.w	d1,d0
		blt.b	.ok

		addq.w	#1,d2



--
Sam os4.1, e-uae 39bb2 - A4000d 39bb2 - Cyberst.MK3 060 50mhz 128mb - Cybervis. - Ariadne_II - ide DVD und 320gb HD (nur 128gb) - HD Floppy -- A500 3.1 adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

[ Dieser Beitrag wurde von AGSzabo am 16.08.2009 um 06:37 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

16.08.2009, 08:15 Uhr

thomas
Posts: 7718
Nutzer

Was hat Runden mit Wordwrap zu tun ?

Ich würde das so machen:

code:
move.l	d1,d2
	lsr.l	#1,d2
	add.l	d2,d0
	divu	d1,d0



Zum Wordwrap, das ist ja nun kein weltbewegender Algorithmus. Einfach für jedes Wort prüfen, ob es noch in die Zeile paßt. Wenn ja, drucken, wenn nein, nächste Zeile. Einziger Sonderfall ist, wenn das erste Wort der Zeile schon nicht reinpaßt. Dann muß man es abschneiden.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

16.08.2009, 13:39 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von thomas:
Zum Wordwrap, das ist ja nun kein weltbewegender Algorithmus. Einfach für jedes Wort prüfen, ob es noch in die Zeile paßt. Wenn ja, drucken, wenn nein, nächste Zeile. Einziger Sonderfall ist, wenn das erste Wort der Zeile schon nicht reinpaßt. Dann muß man es abschneiden.

Na ja, je nach Anwendungsfall gibt es schon ein paar Entscheidungen mehr, die man treffen kann.
Die erste Frage, die man beantworten muss, ist: "was ist ein Wort?". Je nach verwendeten Zeichensatz gibt es neben Leerzeichen noch andere Breaks, die einen Umbruch erlauben. Außerdem kann man nach bestimmten Interpunktionszeichen umbrechen, selbst dann, wenn nach diesen kein Leerzeichen folgt. Zusätzlich gibt es noch die Möglichkeit, Soft-Hyphens zu unterstützen.

Ob Dein Browser z.B: Soft-Hyphens unterstützt, kannst Du überprüfen, in dem Du das Fenster kleiner machst:

Donau­dampf­schiff­fahrts­gesellschafts­kapitäns­mützen­innen­futter­her­stel­ler­firmen­betriebsrats­sitzungs­zimmer­tapeten­lieferanten­eingangs­tür­schloss­schlüssel­loch ¹

Wenn man diese Frage beantwortet hat, sollte man überlegen, ob man nur Schriften mit fester Breite unterstützt, oder auch proportional Schriften.

Bei fester Breite kann man die benötigte Breite einfach durch Anzahl Zeichen mal Breite berechnen (Ausnahme Soft-Hyphens), somit lohnt sich, die Umbruchstelle mit einer Binären Suche zu ermitteln.

Bei Proportionalschriften wird dagegen ohnehin die benötigte Breite durch Iterieren und Aufsummieren der Zeichenbreiten berechnet, womit man also besser linear nach der Umbruchstelle sucht.

Dann gilt es noch die Entscheidung zu treffen, wie man mit whitespace im Allgemeinen umgeht. Ignoriert man Kombinationen von Leerzeichen so wie bei Html, oder respektiert man sie, um Einrückungen oder ähnliche Formatierungen zu erlauben. Besteht eine Zeile nur aus Einrückung am Anfang und einem einzigen, nicht trennbaren Wort, das nicht mehr in die Zeile passt, gibt es drei Möglichkeiten:
  • die Zeile so lassen
  • die Einrückung reduzieren
  • zwischen Einrückung und Beginn des Wortes umbrechen

    und wenn das Wort dann immer noch nicht reinpasst, gibt es auch mehrere Möglichkeiten.
  • Abschneiden, wie von Dir genannt
  • Komponente vergrößern oder über den reservierten Bereich hinausschreiben (evtl. auch scrollen)
  • Ausnahmsweise innerhalb eines Wortes umbrechen

    mfg

    ¹ Nachtrag: Zumindest bei mir bricht Firefox das lange Wort im Beitrag nicht um, wenn man die Zitierfunktion benutzt, wird im Textfeld dagegen richtig umgebrochen. Beim http://de.wikipedia.org/wiki/Weiches_Trennzeichen geht es auch.


    [ Dieser Beitrag wurde von Holger am 16.08.2009 um 13:51 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

  • 17.08.2009, 15:18 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    der wordwrap hat selbstverständlich nichts mit der rundung zu tun. es sollte blos ein beispiel sein dass ich auch selber denken kann.

    bei dem wordwrap wollte ich es so machen, dass wenn nur ein wort in der zeile ist, dieses mit layers geclipt wird. die länge einer zeile lässt sich mit TextLenght oder so ausmessen. von proportionalschrifen wird dabei ausgegangen, dazu ist die funktion gedacht.

    die idee mit den nbsp ist gut. geplant ist zumidest, dass man steuercodes einfügen kann um die farbe oder den stil zu ändern. immer ein byte steuercode und ein byte stil oder farbe. bestehende $a sollen als muss-umbruch gehandhabt werden.

    ich verstehe noch nicht ganz was softhyphens sind.

    die rundungsroutine ist cool! leider verstehe ich sie noch nicht ganz. kannst du sie vielleicht kommentieren?

    :itchy:
    --
    Sam os4.1, e-uae 39bb2 - A4000d 39bb2 - Cyberst.MK3 060 50mhz 128mb - Cybervis. - Ariadne_II - ide DVD und 320gb HD (nur 128gb) - HD Floppy -- A500 3.1 adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ - Antworten - Zitieren - Direktlink - ]

    17.08.2009, 15:42 Uhr

    thomas
    Posts: 7718
    Nutzer
    @AGSzabo:

    Zitat:
    ich verstehe noch nicht ganz was softhyphens sind.

    Silbentrennung.


    Zitat:
    die rundungsroutine ist cool! leider verstehe ich sie noch nicht ganz. kannst du sie vielleicht kommentieren?

    Normales Runden auf die Einerstelle bedeutet, 0.5 addieren und dann die Nachkommastellen abschneiden.

    Also trunc(a / b + 0.5).

    Da wir aber keine Nachkommastellen haben, müssen wir das irgendwie umbauen. Also erstmal alles auf einen Bruch:

    a / b + 0.5 =
    a / b + (b * 0.5) / b =
    (a + b * 0.5) / b

    Und b * 0.5 kann man auch als b * 1/2 oder b / 2 schreiben. Also

    (a + b / 2) / b

    Und das in Assembler ergibt das das obige.

    Gruß Thomas

    --
    Email: thomas-rapp@web.de
    Home: thomas-rapp.homepage.t-online.de/

    [ Dieser Beitrag wurde von thomas am 17.08.2009 um 15:42 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

    17.08.2009, 15:52 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @thomas:

    wow. mathematikuntericht habe ich gehasst und den lehrer isb. aber jetzt verstehe ich wie du drauf gekommen bist. mein gedanke war, mit derm rest zu arbeiten: wenn der rest größer ist als der halbe teiler, wird 1 addiert. offenbar gibt es sogar fuer so kleine probleme ganz verschiedene lösungen.
    --
    Sam os4.1, e-uae 39bb2 - A4000d 39bb2 - Cyberst.MK3 060 50mhz 128mb - Cybervis. - Ariadne_II - ide DVD und 320gb HD (nur 128gb) - HD Floppy -- A500 3.1 adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ - Antworten - Zitieren - Direktlink - ]

    17.08.2009, 18:47 Uhr

    Holger
    Posts: 8116
    Nutzer
    Zitat:
    Original von AGSzabo:
    der wordwrap hat selbstverständlich nichts mit der rundung zu tun. es sollte blos ein beispiel sein dass ich auch selber denken kann.

    Ja, diese Vorgehensweise kennen wir inzwischen auch von Dir. Es geht aber nicht darum, ob Du selber denken kannst, sondern ob Du es auch in Bezug auf Dein Problem schon mal versucht hast.
    Code-Schnippsel ohne Zusammenhang helfen niemanden.

    Oder möchtest Du, dass wir Dir in Zukunft auch Antworten mit Code-Schnippseln geben, die nichts mit der Frage zu tun haben? :P
    Zitat:
    bei dem wordwrap wollte ich es so machen, dass wenn nur ein wort in der zeile ist, dieses mit layers geclipt wird. ...
    bestehende $a sollen als muss-umbruch gehandhabt werden.

    Hehe, das sind sogar mal brauchbare Informationen. ;) Weiter so!
    Zitat:
    ich verstehe noch nicht ganz was softhyphens sind.
    Steht doch in dem verlinkten Wikipedia-Artikel.
    Es ist ein Zeichen, das eine Stelle mit erlaubten Umbruch zwecks Silbentrennung markiert. Wenn kein Umbruch erfolgt, ist das Zeichen unsichtbar, wenn an dieser Stelle umgebrochen wird, erscheint vor dem Umbruch ein Trennzeichen (Bindestrich).

    mfg

    --
    Good coders do not comment. What was hard to write should be hard to read too.

    [ - Antworten - Zitieren - Direktlink - ]

    17.08.2009, 19:22 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @Holger:
    > Ja, diese Vorgehensweise kennen wir inzwischen auch von Dir. Es geht aber nicht darum, ob Du selber denken kannst, sondern ob Du es auch in Bezug auf Dein Problem schon mal versucht hast.
    Code-Schnippsel ohne Zusammenhang helfen niemanden.

    doch das hängt zusammen, ich brauche das fuer das prop-slider gadget. ich arbeite an mehr problemen als man hier sieht, auch wenn es so aussieht als würde ich alles uebers forum machen, das ist nicht wahr.

    welche vorgehensweise meinst du?

    btw, dieses propding hat noch einen großen fehler: man muss die maus auf die ganze länge des knopfes runter oder rauf ziehen anstelle dass man ihn an einer fixen griffstelle bewegen kann. um das zu verstehen muss man es evtl ausprobieren.

    aber auch so ein wordwrap wiederum kann es schon in sich haben, das haben wir hier gesehen.
    --
    Sam os4.1, e-uae 39bb2 - A4000d 39bb2 - Cyberst.MK3 060 50mhz 128mb - Cybervis. - Ariadne_II - ide DVD und 320gb HD (nur 128gb) - HD Floppy -- A500 3.1 adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ - Antworten - Zitieren - Direktlink - ]

    18.08.2009, 11:16 Uhr

    Holger
    Posts: 8116
    Nutzer
    Zitat:
    Original von AGSzabo:
    doch das hängt zusammen, ich brauche das fuer das prop-slider gadget. ich arbeite an mehr problemen als man hier sieht, auch wenn es so aussieht als würde ich alles uebers forum machen, das ist nicht wahr.

    Das ist vollkommen klar, dass Du an noch mehr Dingen arbeiten musst, hat ja keiner behauptet, ein vollständiges Toolkit wäre leicht zu programmieren. Ob das nun so geschickt ist, diese verschiedenen Dinge gleichzeitig zu machen, ist eine andere Frage.

    Zitat:
    btw, dieses propding hat noch einen großen fehler: man muss die maus auf die ganze länge des knopfes runter oder rauf ziehen anstelle dass man ihn an einer fixen griffstelle bewegen kann. um das zu verstehen muss man es evtl ausprobieren.
    Das kann man sich sehr gut vorstellen, ohne es sich anzusehen.
    Das "propding" besitzt eine Gesamtlänge und ein Knopflänge, die den gesamten Wertebereich und einen sichtbaren Ausschnitt daraus repräsentieren. Nun muss die Mausbewegung in (Gadgetgröße-Knopflänge) auch auf (Wertebereich-sichtbarer Bereich) projiziert werden.

    Fehlerquellen sind zum einen eine mögliche Verwechslung dieser Größen, zum anderen wird bei sehr kleinem sichtbarem Bereich der Knopf größer dargestellt, also nicht mehr proportional, da der Knopf i.A. eine Mindestgröße hat. Wenn man dann Wertebereich auf Gadgetgröße projiziert, statt (Wertebereich-sichtbarer Bereich) auf (Gadgetgröße-Knopflänge), entsteht eine Abweichung.

    mfg

    --
    Good coders do not comment. What was hard to write should be hard to read too.

    [ - Antworten - Zitieren - Direktlink - ]

    18.08.2009, 16:41 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @Holger:

    >Das kann man sich sehr gut vorstellen, ohne es sich anzusehen.

    ah ja, gut.


    die knopfgröße hab ich griff und die knopfposition auch. es gibt eine mindestgröße die mit einbezogen wird und obwohl der max-wert zb blos zb 10 ist, scrollt der knopf butterweich dank interner arbeit mit hohen werten (und double buffering), die auf den einstellbaren wertebreich umgerechnet werden. nur der angriffspunkt bleibt nicht konstant sondern wandert im knopf mit, so dass man die maus viel weiter ziehen muss um von der stelle zu kommen. ich weis blos noch nicht warum.
    --
    Sam os4.1, e-uae 39bb2 - A4000d 39bb2 - Cyberst.MK3 060 50mhz 128mb - Cybervis. - Ariadne_II - ide DVD und 320gb HD (nur 128gb) - HD Floppy -- A500 3.1 adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ - Antworten - Zitieren - Direktlink - ]

    08.11.2009, 12:50 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    endlich gefunden:

    eine pseudocode routine zum umbrechen des texts:

    code:
    SpaceLeft := LineWidth
    for each Word in Text
        if Width(Word) > SpaceLeft
            if not firstword insert line break before Word in Text
            SpaceLeft := LineWidth - Width(Word)
        else
            SpaceLeft := SpaceLeft - (Width(Word) + SpaceWidth)


    leider funktioniert meine umsetzung noch nicht wie sie soll. hat da jemand evtl eine idee? der text wird manchmal an stellen umgebrochen an denen kein umbruch passieren dürfte und die resultierenden zeilen sind 1 pixel zu breit.

    code:
    ; calc and store width of space
    
    		lea	.space(pc),a0
    		moveq	#1,d0
    		move.l	a2,a1
    		jsr	_LVOTextLength(a6)
    		move.w	d0,d7		; width of 1 space char
    
    		moveq	#-1,d6		; first word
    
    		; get textfield width
    
    		move.w	xuiFd_width(a3),d5
    
    .first_spc_left	; SpaceLeft = LineWidth
    
    		move.w	d5,d4		; space left
    
    		lea	text(pc),a5
    
    		move.l	a5,a4
    
    .words_loop	; find word
    
    		addq	#1,d6		; count word
    
    		moveq	#0,d0		; word lenght in chars
    
    .find_loop	tst.b	(a4)
    		beq.b	.word_found
    
    		cmp.b	#" ",(a4)
    		beq.b	.word_found
    
    		cmp.b	#$a,(a4)
    		beq.b	.word_found
    
    		addq	#1,a4
    		addq	#1,d0
    		bra.b	.find_loop
    
    .word_found	; for each Word in Text
    
    		; calc width of word
    
    		move.l	a5,a0
    		move.l	a2,a1
    		jsr	_LVOTextLength(a6)
    
    		; if Width(Word) > SpaceLeft
    
    		cmp.w	d4,d0
    		ble.b	.sub_word
    
    		; if not firstword insert line break before Word in Text
    
    		tst.w	d6
    		beq.b	.init_line
    
    		move.b	#$a,-1(a5)
    
    .init_line	; SpaceLeft := LineWidth - Width(Word)
    
    		move.w	d5,d4
    		sub.w	d0,d4	
    
    		bra.b	.next_word
    
    .sub_word	; SpaceLeft = SpaceLeft - (Width(Word) + SpaceWidth)
    
    		sub.w	d0,d4
    		sub.w	d7,d4
    
    .next_word	tst.b	(a4)		; end of text?
    		beq.b	.rts
    		addq	#1,a4		; if not, step to beginning of next word
    		move.l	a4,a5
    		bra.b	.words_loop
    
    .rts		rts
    
    .space		dc.b	" "
    		even
    
    .text		dc.b	"Use the first 4 colors (or pens) only and map "
    		dc.b	"them into the higher.",$a,$a
    		dc.b	"For example: buttonpen and tabspen are replaced by backpen.",$a,$a
    		dc.b	"This is usefull if you like retro-style and don't "
    		dc.b	"want to config the whole lot of pens separately.",$a,$a
    		dc.b	"Use this also on low-color screens.",0


    --
    Sam mini os4.1 -- e-uae 39bb2 -- A4000D 3.0 - 2mbchip/8mbfast - Ariadne_II - ide DVD und HD -- A500 3.1 (mkick) adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ Dieser Beitrag wurde von AGSzabo am 08.11.2009 um 13:43 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

    08.11.2009, 18:40 Uhr

    Holger
    Posts: 8116
    Nutzer
    Zitat:
    Original von AGSzabo:
    eine pseudocode routine zum umbrechen des texts:
    code:
    SpaceLeft := LineWidth
    for each Word in Text
        if Width(Word) > SpaceLeft
            if not firstword insert line break before Word in Text
            SpaceLeft := LineWidth - Width(Word)
        else
            SpaceLeft := SpaceLeft - (Width(Word) + SpaceWidth)


    Da es sehr unwahrscheinlich ist, dass schon das erste Wort nicht in eine Zeile passt, hast Du schon beim ersten Wort eine Inkonsistenz: Du behandelst das erste Wort nicht wir einen Zeilenanfang, ziehst also schon ein Leerzeichen ab, obwohl das erste Wort am Anfang einer Zeile steht. Wenn Du vom verfügbaren Platz nur die bereits gesetzten Leerzeichen abziehst, muss Du außerdem beim Test, ob eine weiteres Wort in die Zeile passt, auch überprüfen, ob das zugehörige Leerzeichen in die Zeile passt.

    Das zweite Problem besteht darin, dass Du nicht definierst, was ein Wort ist. Deine Implementierung geht davon aus, dass ein Wort auch an einem expliziten Zeilenumbruch endet. Das ist zwar nicht verkehrt, aber damit funktioniert der oben stehende Pseudo-Code nicht, denn der behandelt jedes Wort-Ende wie ein Leerzeichen.

    --
    Good coders do not comment. What was hard to write should be hard to read too.

    [ - Antworten - Zitieren - Direktlink - ]

    08.11.2009, 19:05 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @Holger:

    den code hab ich auf wikipedia gefunden:

    http://en.wikipedia.org/wiki/Word_wrap#Minimum_length

    Da war aber schon ein fehler drin: das erste wort des textes wenn es nicht in die zeile passte bekam auch ein $a vorausgesetzt (das würde aber im falle des falles in fremden speicher schreiben). daher habe ich eigebaut "if not firstword" (des textes, nicht der zeile).

    ein wort ist eine beliebige ascii-zeichenkette bis zum nächsten leerzeichen " ", zeilenumbruch $a oder textende 0.

    ich prüfe nochmal ob ich das jetzt besser machen kann, danke. ich verstehe blos noch nicht was du mit "nicht wie einen zeilenanfang" meinst und wo und wieso ich da nochmal die spacebreite dazuaddieren soll.

    so ist es jetzt:

    code:
    SpaceLeft := LineWidth
    for each Word in Text
        if Width(Word) > SpaceLeft
            if not firstword insert line break before Word in Text
    a       SpaceLeft := LineWidth - Width(Word)
            break
        else
            if char = $a goto a
            SpaceLeft := SpaceLeft - (Width(Word) + SpaceWidth)



    --
    Sam mini os4.1 -- e-uae 39bb2 -- A4000D 3.0 - 2mbchip/8mbfast - Ariadne_II - ide DVD und HD -- A500 3.1 (mkick) adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ Dieser Beitrag wurde von AGSzabo am 08.11.2009 um 19:19 Uhr geändert. ]

    [ Dieser Beitrag wurde von AGSzabo am 08.11.2009 um 19:23 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

    09.11.2009, 01:08 Uhr

    inq
    Posts: 445
    Nutzer
    Zitat:
    Original von AGSzabo:
    @Holger:
    den code hab ich auf wikipedia gefunden:
    http://en.wikipedia.org/wiki/Word_wrap#Minimum_length

    ein wort ist eine beliebige ascii-zeichenkette bis zum nächsten leerzeichen " ", zeilenumbruch $a oder textende 0.


    müsstest du natürlich noch spezifizieren: unsichtbare leerzeichen, silbentrenner, semikolon, (doppel)punkt, ...

    gruss
    inq

    [ - Antworten - Zitieren - Direktlink - ]

    09.11.2009, 08:37 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @inq:

    >müsstest du natürlich noch spezifizieren: unsichtbare leerzeichen, silbentrenner, semikolon, (doppel)punkt, ...

    nein, nichts dergleichen. einfach nur " ", $a oder 0. keep it simple. aber was mich noch interessieren würde, wären steuercodes zum ändern des stils oder der farbe aber das ist eine andere geschichte.

    --
    Sam mini os4.1 -- e-uae 39bb2 -- A4000D 3.0 - 2mbchip/8mbfast - Ariadne_II - ide DVD und HD -- A500 3.1 (mkick) adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ Dieser Beitrag wurde von AGSzabo am 09.11.2009 um 08:47 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

    09.11.2009, 10:55 Uhr

    Thore
    Posts: 2266
    Nutzer
    Vergiss den "harten" Umbruch ($D,$A) nicht =)

    [ - Antworten - Zitieren - Direktlink - ]

    09.11.2009, 11:10 Uhr

    Holger
    Posts: 8116
    Nutzer
    Zitat:
    Original von AGSzabo:
    Da war aber schon ein fehler drin: das erste wort des textes wenn es nicht in die zeile passte bekam auch ein $a vorausgesetzt (das würde aber im falle des falles in fremden speicher schreiben).

    Ja, wenn Du den Ausgangstext veränderst. Davon ist der Verfasser des Pseudocodes bestimmt nicht ausgegangen. Trotzdem ist es natürlich richtig, dass ein Zeilenumbruch vor dem ersten Wort eigentlich unerwünscht ist.
    Zitat:
    ich verstehe blos noch nicht was du mit "nicht wie einen zeilenanfang" meinst und wo und wieso ich da nochmal die spacebreite dazuaddieren soll.

    so ist es jetzt:

    code:
    SpaceLeft := LineWidth
    for each Word in Text
        if Width(Word) > SpaceLeft
            if not firstword insert line break before Word in Text
    a       SpaceLeft := LineWidth - Width(Word)
            break
        else
            if char = $a goto a
            SpaceLeft := SpaceLeft - (Width(Word) + SpaceWidth)


    Du hast zwei verschiedene Anweisungen, die den verfügbaren Platz reduzieren, die rote gilt im Normalfall für das erste Wort einer Zeile (wird direkt nach dem Zeilenumbruch angewandt) und die grüne für jedes weitere Wort. Nur die grüne zieht den Platz für ein Leerzeichen ab, was auch richtig ist:
    Wort1_Wort2
    Wort1_Wort2_Wort3
    Wort1_Wort2..._Wortn

    Der Algorithmus schlägt allerdings für das erste Wort des gesamten Textes fehl. Geh in Gedanken (oder im Debugger) einfach den Code durch, wie er beim ersten Durchlauf ausgeführt wird. Wenn das Wort in die Zeile passt, wird die grüne Anweisung ausgeführt, es müsst aber immer die rote sein, da das erste Wort des gesamten Textes auch immer am Anfang einer Zeile steht.

    Hoffe, das war jetzt verständlicher. I-)
    --
    Good coders do not comment. What was hard to write should be hard to read too.

    [ - Antworten - Zitieren - Direktlink - ]

    09.11.2009, 13:10 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @Holger:

    > insert line break before Word in Text

    für mich fühlt sich das so an als wolle er den ausgangstext verändern.

    ah ja, ich sehe es. aber es ist für mich fast unglaublich dass in wikipedia so ein schmarrn steht obwohl weiter untem in artikel ganz komplexe formeln vorkommen.

    code:
    SpaceLeft := LineWidth
    for each Word in Text
        if Width(Word) > SpaceLeft
            if not firstword insert line break before Word in Text
    a       SpaceLeft := LineWidth - Width(Word)
            break
        else
            if char = $a goto a
            if first word goto a
            SpaceLeft := SpaceLeft - (Width(Word) + SpaceWidth)


    >Vergiss den "harten" Umbruch ($D,$A) nicht =)

    was ist das, kommt bei mir nicht vor.

    --
    Sam mini os4.1 -- e-uae 39bb2 -- A4000D 3.0 - 2mbchip/8mbfast - Ariadne_II - ide DVD und HD -- A500 3.1 (mkick) adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ Dieser Beitrag wurde von AGSzabo am 09.11.2009 um 13:22 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

    09.11.2009, 13:38 Uhr

    Holger
    Posts: 8116
    Nutzer
    Zitat:
    Original von AGSzabo:
    > insert line break before Word in Text
    für mich fühlt sich das so an als wolle er den ausgangstext verändern.

    Nee, über die Datenhaltung sollte man da nicht spekulieren. insert heißt ja nicht, dass etwas überschrieben wird. Es könnte tatsächlich verschieben der nachfolgenden Daten bedeuten, oder eben, dass der formatierte Text woanders liegt als der Ausgangstext, was man, wenn die Größe der GUI im Nachhinein verändert werden kann, sowieso tun müsste.
    Zitat:
    ah ja, ich sehe es. aber es ist für mich fast unglaublich dass in wikipedia so ein schmarrn steht ...
    Wikipedia ist kein Programmiererhandbuch. Der Pseudocode sieht eigentlich schon auf den ersten Blick nicht so aus, als ob er hohe Ansprüche erfüllen soll.
    Vielleicht interpretierst Du nur zuviel da rein.

    Zitat:
    code:
    ...


    Hmm, der Code hat immer noch den Fehler, dass er zwar prüft, ob Platz für das nächste Wort ist, aber nicht prüft, ob auch Platz für das zugehörige Leerzeichen ist. Somit besteht immer die Möglichkeit, dass der Text um ein paar Pixel zu breit formatiert wird. Eben bis zur Breite eines Leerzeichens.

    Außerdem ist es etwas ineffizient, für jedes Wort die Bedingung "first word" zu prüfen, die nur ein einziges Mal erfüllt ist.

    code:
    while( ( word:=next() ) )
        SpaceLeft := LineWidth - Width(word)
        while( ( word:=next() ) AND char<>$a AND Width(word)+SpaceWidth<SpaceLeft)
          SpaceLeft := SpaceLeft - (Width(word)+SpaceWidth)
        end while
        insert line break
    end while



    [ Dieser Beitrag wurde von Holger am 09.11.2009 um 13:40 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

    09.11.2009, 13:40 Uhr

    Holger
    Posts: 8116
    Nutzer
    Zitat:
    Original von AGSzabo:
    >Vergiss den "harten" Umbruch ($D,$A) nicht =)

    was ist das, kommt bei mir nicht vor.

    Stimmt ja nicht, $A berücksichtigst Du doch...

    --
    Good coders do not comment. What was hard to write should be hard to read too.

    [ - Antworten - Zitieren - Direktlink - ]

    09.11.2009, 14:08 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @Holger:

    >Stimmt ja nicht, $A berücksichtigst Du doch...

    aber $d nicht. das kommt bei mir nich vor

    >oder eben, dass der formatierte Text woanders liegt als der Ausgangstext, was man, wenn die Größe der GUI im Nachhinein verändert werden kann, sowieso tun müsste.

    bei mir ist es so dass der text vor der formatierung in einen neuen buffer kopiert wird, damit man beim nächstenmal nicht die eingefügten $a alle als hardwraps versteht.

    > Somit besteht immer die Möglichkeit, dass der Text um ein paar Pixel zu breit formatiert wird. Eben bis zur Breite eines Leerzeichens.

    scheint nicht vor zu kommen.
    --
    Sam mini os4.1 -- e-uae 39bb2 -- A4000D 3.0 - 2mbchip/8mbfast - Ariadne_II - ide DVD und HD -- A500 3.1 (mkick) adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ - Antworten - Zitieren - Direktlink - ]

    11.11.2009, 04:49 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    als nächstes soll der text formatierungszeichen enhalten können, um stil und farbe zu beeinflussen. ist es sinnvoll jedes zeichen einzeln auszugeben (overhead?) oder sollte ich immer so viele zeichen wie möglich auf einmal schreiben (mehr berechnung)?

    außerdem brächten steuerzeichen die umbruchberechnung durcheinander! wie komme ich da drumrum oder zu einer lösung?

    [ Dieser Beitrag wurde von AGSzabo am 11.11.2009 um 04:53 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

    11.11.2009, 12:19 Uhr

    Holger
    Posts: 8116
    Nutzer
    Zitat:
    Original von AGSzabo:
    ist es sinnvoll jedes zeichen einzeln auszugeben (overhead?) oder sollte ich immer so viele zeichen wie möglich auf einmal schreiben (mehr berechnung)?

    Grundsätzlich gibt es erst mal gar keinen Unterschied, da "viel Zeichen auf einmal schreiben" nichts anderes macht, als diese Zeichen nacheinander auszugeben.

    Praktisch entsteht dann ein Unterschied, wenn Du eine externe Routine, wie die des Betriebssystems und/oder einer Render-Engine aufrufst. Wenn diese dann noch Anti-Aliasing oder Kerning richtig unterstützen soll, musst Du die Zeichensequenz als Ganzes übergeben.

    Oder alles selber machen.
    Zitat:
    außerdem brächten steuerzeichen die umbruchberechnung durcheinander!
    Nur wenn sie a) mit sichtbaren Zeichen kollidieren, bzw., aus Sicht der verwendeten Routine eine Breite haben oder b) die Formatierung so ändern, dass sie Auswirkungen auf die Zeichenbreite haben (Fettdruck, Schriftart oder -größe).
    Zitat:
    wie komme ich da drumrum oder zu einer lösung?
    Du kommst nicht drumrum.
    Aus diesem Grund ist es eben um ein Vielfaches besser, erst die zu unterstützenden Features zu spezifizieren, und dann einen Algorithmus zu entwickeln, der diese Zielstellung erfüllt.

    Erst irgendetwas entwickeln und dann was neues einbauen, ist ein sicherer Weg, regelmäßig Code für die Tonne zu entwickeln.

    Die Lösung hängt natürlich wieder davon ab, was unterstützt werden soll. Sind Steuerzeichen z.B. innerhalb eines Wortes erlaubt oder nicht.

    --
    Good coders do not comment. What was hard to write should be hard to read too.

    [ - Antworten - Zitieren - Direktlink - ]

    11.11.2009, 12:56 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @Holger:

    >Nur wenn sie a) mit sichtbaren Zeichen kollidieren, bzw., aus Sicht der verwendeten Routine eine Breite haben oder b) die Formatierung so ändern, dass sie Auswirkungen auf die Zeichenbreite haben (Fettdruck, Schriftart oder -größe).

    wenn ein formatierungszeichen gefunden wird, dass nichts an der zeichenbreite und evtl größe ändert, muss es übergangen werden. der andere fall ist kompliziert und ich habe daran diesmal noch garnicht gedacht (vor ein paar jahren wollte ich so eine routine schonmal schreiben aber habe es nicht ganz geschafft, es wurde da aueßerdem für jeden bestandteil eine eigene node angelegt... was evtl garnicht nötig ist).


    >Erst irgendetwas entwickeln und dann was neues einbauen, ist ein sicherer Weg, regelmäßig Code für die Tonne zu entwickeln.

    du hast natürlich recht und ich bin ja so dumm, aber beim duschen ist mir ein argument eingefallen, nämlich das man bei der teilweisen umsetzung eines problems schießlich näher sich damit auseinandersetzt und somit auch näher zur gesamtlösung ist, wenn das ganze problem zu unüberschaubar ist.

    > Sind Steuerzeichen z.B. innerhalb eines Wortes erlaubt oder nicht.

    ja, sind sie.
    --
    Sam mini os4.1 -- e-uae 39bb2 -- A4000D 3.0 - 2mbchip/8mbfast - Ariadne_II - ide DVD und HD -- A500 3.1 (mkick) adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ - Antworten - Zitieren - Direktlink - ]

    11.11.2009, 13:24 Uhr

    Der_Wanderer
    Posts: 1229
    Nutzer
    Einzelzeichen sind keine gute Idee.

    Zwei Möglichkeiten kann ich empfehlen:

    1. Du benutzt in deinem String ein Escape Zeichen, dem dann ein Steuercode folgt. So kannst du durch den String suchen und dann immer zusammenhängende Text Teile zeichen.
    Im ASCII gibt es daüfr ein extra reserviertes Zeichen nämlich #27.
    Zum lesen ersetze ich es hier mit dem Backslash, wenn es Human-editable sein soll.

    Beispiel.

    "Ich bin ein Text, und habe bein dickesx Wort und eins in iitallicx."

    Wenn da Escape Symbol selbst vorkommen soll, escaped man es mit sich selbst, so muss man keine Annahmen über das Alphabet des Textes machen.

    Das "x" habe ich benutzt als "nehme letze Definiton zurück".
    Das hat sich bei Syntax highlighning bewährt.

    Beispiel

    "Ich bin ein bText, der ab ihier auch noch itallic ist,x jetzt nur noch bold und x jetzt wieder normal. Backslashes \ gehen auch."

    Das ist nicht unbedingt das aller aller schnellste, weil du den String durchsuchen musst, aber es ist brauchbar schnell und hat wenig Book-Keeping Aufwand.

    2. Du lässt den Text String wie er ist, und stellst die Formatierungsinformation vornedran.

    Beispiel:
    "n30b6i8bi12tDas ist ein Text, der kann bold, italic, bold+italic."

    hier habe ich noch n für normal und t für den Textbegin. Das wäre am schnellsten abzuarbeiten, erfordert aber mehr Aufwand wenn der Text editiert wird.


    --
    HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, AB3 Includes und viele mehr...
    Homepage: http://www.hd-rec.de


    [ - Antworten - Zitieren - Direktlink - ]

    11.11.2009, 13:31 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @Holger

    code:
    while( ( word:=next() ) )
        SpaceLeft := LineWidth - Width(word)
        while( ( word:=next() ) AND char<>$a AND Width(word)+SpaceWidth<SpaceLeft)
          SpaceLeft := SpaceLeft - (Width(word)+SpaceWidth)
        end while
        insert line break
    end while


    diese routine fügt vor dem letzten wort immer einen umbruch ein. das "insert line break" wird beim letzten durchlauf immer ausgeführt, also für das letzte wort.

    --
    Sam mini os4.1 -- e-uae 39bb2 -- A4000D 3.0 - 2mbchip/8mbfast - Ariadne_II - ide DVD und HD -- A500 3.1 (mkick) adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ - Antworten - Zitieren - Direktlink - ]

    11.11.2009, 14:31 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @Der_Wanderer:
    > Einzelzeichen sind keine gute Idee.

    hm... wohl so
    --
    Sam mini os4.1 -- e-uae 39bb2 -- A4000D 3.0 - 2mbchip/8mbfast - Ariadne_II - ide DVD und HD -- A500 3.1 (mkick) adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP -- BenQ FP93G TFT - 1048 like CRT - HP psc1110

    [ Dieser Beitrag wurde von AGSzabo am 11.11.2009 um 14:34 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

    11.11.2009, 15:22 Uhr

    Holger
    Posts: 8116
    Nutzer
    Zitat:
    Original von AGSzabo:
    diese routine fügt vor dem letzten wort immer einen umbruch ein. das "insert line break" wird beim letzten durchlauf immer ausgeführt, also für das letzte wort.

    Das war mir bewusst, ich wusste nur nicht, ob das überhaupt stört.
    Wenn man den Code effizient halten will, sollte man versuchen, möglichst wenig innerhalb einer Schleife auszuführen, insbesondere möglichst wenig Fallunterscheidungen.

    Deshalb ist es kein Problem, besondere Randbedingungen zu haben, solange man sie außerhalb der Schleife behandelt.

    Wenn man also weiß, dass in jedem Fall ein Zeilenumbruch nach dem letzten Wort hinzugefügt wird, entfernt man es einfach ganz am Ende der Routine. Da es eine Ausnahme gibt, nämlich, wenn es überhaupt keine Wörter gibt, überprüft man genau diesen Spezialfall ganz am Anfang der Routine.

    code:
    if no next word return    =>empty text
    while( ( word:=next() ) )
        SpaceLeft := LineWidth - Width(word)
        while( ( word:=next() ) AND char<>$a AND Width(word)+SpaceWidth<SpaceLeft)
          SpaceLeft := SpaceLeft - (Width(word)+SpaceWidth)
        end while
        insert line break
    end while
    remove last line break


    Zitat:
    Original von AGSzabo:
    > Sind Steuerzeichen z.B. innerhalb eines Wortes erlaubt oder nicht.

    ja, sind sie.

    Dann wird's schwierig. Es empfiehlt sich, Text und Formatierung getrennt zu verarbeiten. Das heißt nicht, dass der Ausgangstext keine Steuerzeichen enthalten darf, sondern dass Du diese Information bei dem sowieso stattfindenden Kopiervorgang extrahierst.

    Dann hast Du einen Text ohne Steuerzeichen, den Du der graphics.library übergeben kannst, und eine Tabelle, die Dir die Bereiche mitteilt, die mit einem einfachen Algorithmus bearbeitet werden können, und wo besonderes Handling erforderlich ist.

    --
    Good coders do not comment. What was hard to write should be hard to read too.

    [ - Antworten - Zitieren - Direktlink - ]

    12.11.2009, 12:42 Uhr

    AGSzabo
    Posts: 1663
    Nutzer
    @Holger:

    >und eine Tabelle, die Dir die Bereiche mitteilt, die mit einem einfachen Algorithmus bearbeitet werden können, und wo besonderes Handling erforderlich ist.

    wie sollte oder könnte diese tabelle aussehen? ich habe überlegt und bin aber nicht weiter gekommen als

    zahl_der_zeichen, stil, farbe, farbe_bg, drawmode
    zahl_der_zeichen, stil, farbe, farbe_bg, drawmode

    wobei zahl der zeichen in der nächsten zeile weiter gehen kann, denn was eine zeile ist, wird erst nach der filterung des strings berechnet. das ist aber unpraktisch weil man dann bei der ausgabe trotz dass man eine zahl_der_zeichen hat, nochmal bis zum ende der zeile suchen muss...

    geht das nicht irgendwie besser? praktischer?
    --
    Sam mini os4.1 -- e-uae 39bb2 -- A4000D 3.0 - 2mbchip/8mbfast - Ariadne_II - ide DVD und HD -- A500 3.1 (mkick) adide 50mb -- Duron 1600mhz Ubuntu Linux / WinXP

    [ Dieser Beitrag wurde von AGSzabo am 12.11.2009 um 13:07 Uhr geändert. ]

    [ - Antworten - Zitieren - Direktlink - ]

    12.11.2009, 13:22 Uhr

    akl
    Posts: 265
    Nutzer
    @AGSzabo:
    Wir wär's mit einem Hash"table", der Dir für einen gegebenen Zeichenindex die Formatierung liefert (oder keine)...

    [ - Antworten - Zitieren - Direktlink - ]


    -1- 2 3 [ - Beitrag schreiben - ]


    amiga-news.de Forum > Programmierung > word wrap [ - Suche - Neue Beiträge - Registrieren - Login - ]


    .
    Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
    Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
    .