[php] Aantal tekens in titel

Pagina: 1
Acties:
  • 155 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Liqued
  • Registratie: Februari 2001
  • Laatst online: 06-08 15:21
Ik heb het volgende probleem:

Ik heb een tabel met daarin titels van hoofdstukken. Nou heeft die tabel een beperkte breedte en wil ik het zo voor elkaar krijgen dat ik elke titel op 1 regel krijg (op 2 regels is echt niet mooi). Je kan het misschien het beste vergelijken met een menu.

Nu heb ik het op dit moment in php zo gedaan dat ie elke titel na een x aantal tekens afkapt en er "..." achter zet (het is tevens ook een link en in de title tag van de link heb ik wel de volledige naam staan).

Nu vind ik dit best een mooie oplossing, maar nu komt het probleem. Als ik het aantal tekens laat afstemmen als ik kijk naar bijvoorbeel hoeveel "O" 's er op die regel kunnen dan vind ik dat ie sommige titels wel veel te snel afkapt (een "i" is nou eenmaal minderbreedt dan een "O").

Hoe zouden jullie dit nou oplossen?

Acties:
  • 0 Henk 'm!

  • Helmet
  • Registratie: Januari 2002
  • Laatst online: 21-08 15:00
Gewoon een paar tekens minder pakken zodat ie altidj wel goed loopt
ik denk dat de "W" het grootst is en datj e daarmee kunt meten

Icons are overrated


Acties:
  • 0 Henk 'm!

  • pietje63
  • Registratie: Juli 2001
  • Laatst online: 08:18

pietje63

RTFM

PHP heeft geen functie die de breedte van letters kent of daar mee om kan gaan.
Je zou zelf een functie kunnen schrijven die aan elke letter een waarde meegeeft van 1 tot 3 (w=3 i=1 t=2 etc) en dan een maximale waarde toestaan.
Dus, als strlen = max; waarde = ?
als waarde te groot, dan string kleiner maken

Dit is wel vrij omslachtig voor php want ik denk dat je het per letter moet doen...

De grootste Nederlandstalige database met informatie over computers met zoekfunctie!!


Acties:
  • 0 Henk 'm!

  • Boogie
  • Registratie: Januari 2001
  • Laatst online: 06-11-2024
Je zou bijna zelf de functie van Pietje in C schrijven en aanbieden aan de php-beoordelaars.
Helaas is mijn C niet goed genoeg.

Acties:
  • 0 Henk 'm!

  • Liqued
  • Registratie: Februari 2001
  • Laatst online: 06-08 15:21
pietje63 schreef op 04 August 2003 @ 21:52:
Dit is wel vrij omslachtig voor php want ik denk dat je het per letter moet doen...
Dat had ik ook al in gedachten en het lijkt me idd beetje veel recources gebruiken. Of valt dat wel mee?

Acties:
  • 0 Henk 'm!

  • pietje63
  • Registratie: Juli 2001
  • Laatst online: 08:18

pietje63

RTFM

Liqued schreef op 04 August 2003 @ 21:56:
[...]


Dat had ik ook al in gedachten en het lijkt me idd beetje veel recources gebruiken. Of valt dat wel mee?
Ik zal zeggen test het uit...
Ik weet niet of er veel titels tegelijk worden getoond en/of de pagina vaak bezocht wordt.

Anders gewoon een pagina maken waarin 100 titels van verschillende lengtes worden gecontroleerd en kijken hoe lang hij er over doet.

De grootste Nederlandstalige database met informatie over computers met zoekfunctie!!


Acties:
  • 0 Henk 'm!

  • Liqued
  • Registratie: Februari 2001
  • Laatst online: 06-08 15:21
Boogie schreef op 04 August 2003 @ 21:55:
Je zou bijna zelf de functie van Pietje in C schrijven en aanbieden aan de php-beoordelaars.
Helaas is mijn C niet goed genoeg.
Denk dat, dat toch iets te veel werk is. Je moet rekening gaan houden met verschillende lettertypes, lettergrotes, bold, italic, etc. Volgens mij werkt het dan ook niet zo relaxed. Teveel parameters om in te voeren per string.

Voor dit individuele geval kan je nog van al dat soort dingetjes gewoon uitgaan van vast staande waarde. Voor php zelf zou het te eenvoudig zijn.

Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 15-09 16:19

alienfruit

the alien you never expected

Ik denk dat je niet kunt bepalen wat de breedte is van een niet propotionele font in PHP. Dit is meer ene grafisch probleem gezien PHP zelf geen ondersteuning heeft voor het tekenen van tekens. Maar misschien kun je dit doen via een CSS2 instelling? In PHP zelf wordt het knap lastig of je zou de GD Library moeten gebruiken maar dan nog steeds kan het zijn dat de client de teksten anders tekenen dan jij berekend hebt.

Dus ik denk dat je het beter bij de huidige oplossing kunt houden, want je kunt toch nooit weten wat de breedtes zijn van het door de client gebruikte lettertype zonder dat je zelf allemaal beschikbaar hebt. Dus ik denk dat je beter er mee moet leven, zulke dingen is alleen leuk als je zelf invloed kan hebben hoe de tekst wordt getekend en dan nog is het soms knap lastig cursief gezette letters teken je toch eerst anders dan normale tekst. Het kost veel tijd als je bijv. je syntax editor fatsoenlijke ondersteuning wilt bieden voor niet fixed fonts (of unicode fonts) zoveel dat ik het tot heden nog niet gelukt is zoals ik wil. Zelf de editor in HomeSite heeft er problemen mee...

[ Voor 19% gewijzigd door alienfruit op 04-08-2003 22:04 ]


Acties:
  • 0 Henk 'm!

  • pietje63
  • Registratie: Juli 2001
  • Laatst online: 08:18

pietje63

RTFM

Als je een vaste breedte van een kolom neemt en ene lettertype kiest dat vrijwel iedereen weet dan gaat het argument van alienfruit niet helemaal op.
Verder kun je de GD-library gewoon de hele titel laten maken en dan kun je de exacte breedte bepalen als je er een plaatje van maakt, je neemt dan alleen wel het risico dat er een halve letter niet op komt te staan en een plaatje maken/laden is volgens mij ook niet alles.

De grootste Nederlandstalige database met informatie over computers met zoekfunctie!!


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 15-09 16:19

alienfruit

the alien you never expected

:Z niet aangedacht |:(
Naja, het blijft altijd een gedoe

pietje63, je moet dan zekers Freetype gebruiken samen met de GD Library???? :?

[ Voor 95% gewijzigd door alienfruit op 04-08-2003 22:10 ]


Acties:
  • 0 Henk 'm!

  • pietje63
  • Registratie: Juli 2001
  • Laatst online: 08:18

pietje63

RTFM

Voorbeeldje van een plaatje maken via php
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
}
if ($mode=="image"){
header("Content-type: image/png");
include ("host.inc");
if (empty($id)){
$email = "verkeerde aanvraag script";
}
else{
mysql_connect("$host", "$gebruiker", "$wachtwoord") or die("Het verbinden met de mysql server is niet gelukt");
mysql_select_db("$database") or die("Het connecten met de database is niet gelukt");
$result=mysql_query("select * from smoelenboek where `id` = '$id' ");
if ($result==""){
$email = "juist persoon niet gevonden in database";
}
while ($row = mysql_fetch_array($result)) {
$email = $row["email"];
}
// einde als id niet ingevoerd is
}
if (empty($email)){
$email = "geen e-mail adres";
}
    $string = "$email";
    $im     = imagecreatefromjpeg("plaatjes/email.jpg");
    $rood = imagecolorallocate($im, 0, 0, 0);
    imagestring($im, 2, 0, 0, $string, $rood);
    imagepng($im);
    imagedestroy($im);
//einde mode image
}
(beetje te uitgebreide code, komt uit een e-mail script van mij om spam-safe e-mail adressen weer te geven)

De grootste Nederlandstalige database met informatie over computers met zoekfunctie!!


Acties:
  • 0 Henk 'm!

Verwijderd

het is volgens mij de beste optie om inderdaad een array te maken waarin je de letters en karacters van waarden voorzien, 1 t/m 3 is inderdaad mooi bedacht!. ;) en met de gdlib kan je heel goed berekenen hoe lang iets wordt, ik zal even een stukje code posten.

PHP:
1
2
3
4
5
6
7
8
    $lengt = (strlen($_GET['text']) * 7);
    $image = imagecreate($lengt,13);
    $color = ImageColorAllocate($image,179,19,19);  // blue 57,109,165
    $white = ImageColorAllocate($image,255,255,255);
    ImageFilledRectangle($image,0,0,110,15,$color);
    imagestring ($image, 3, 1, -1, $_GET['text'], $white);
    Imagepng($image);
    Destroy($image);


Bovenstaande code heeft me nog niet in de steek gelaten :+
zo doe ik het dus ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Ik zou het op een iets andere manier doen, namelijk een berekening.

Stel je text is als volgt:
code:
1
iWiiiiiiW


Eerst moet je tellen hoeveel er van elke letter in de text voorkomen, hier zijn 8x de i te vinden en 2x de W.
Bereken het aantal pixels dat een i lang is en doe dit ook bij de W, doe dan ongeveer het volgende; Pixel * Aantalvandezeletter. Bereken dit van alle letters en tel het bij elkaar op, als het totaal aantal pixels langer is dan X dan er zoveel letters aftrekken als je verwacht dat je text te lang is in pixels.

Het is niet zoveel code, alleen het achterhalen van een pixel is wat meer werk, eerst moet je handmatig alle letter bij elkaar zoeken die even lang zijn in pixels, dan moet je die in een array of een string zetten en dan b.v. met in_array kijken of het voorkomt.

Acties:
  • 0 Henk 'm!

  • pietje63
  • Registratie: Juli 2001
  • Laatst online: 08:18

pietje63

RTFM

Verwijderd schreef op 04 August 2003 @ 23:16:
Ik zou het op een iets andere manier doen, namelijk een berekening.

Stel je text is als volgt:
code:
1
iWiiiiiiW


Eerst moet je tellen hoeveel er van elke letter in de text voorkomen, hier zijn 8x de i te vinden en 2x de W.
Bereken het aantal pixels dat een i lang is en doe dit ook bij de W, doe dan ongeveer het volgende; Pixel * Aantalvandezeletter. Bereken dit van alle letters en tel het bij elkaar op, als het totaal aantal pixels langer is dan X dan er zoveel letters aftrekken als je verwacht dat je text te lang is in pixels.

Het is niet zoveel code, alleen het achterhalen van een pixel is wat meer werk, eerst moet je handmatig alle letter bij elkaar zoeken die even lang zijn in pixels, dan moet je die in een array of een string zetten en dan b.v. met in_array kijken of het voorkomt.
Dit komt volgens mij overeen met wat ik zei, met het verschil dat jij exact in pixels berekent en ik een (makkelijker te maken) systeem met scores van 1-3 doet

De grootste Nederlandstalige database met informatie over computers met zoekfunctie!!


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
waarom plaats je niet gewoon een "overflow: hidden" op hetgeen waarin deze tekst staat. Tis wel een W&G oplossing, maar wel een flink nettere, imo...

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Hier is wat testmateriaal, een array met de breedtes in pixels van Arial 10pts karakters.. Het is een quick & dirty stukje code, heb nu geen tijd meer om er naar te kijken, zal dat morgenavond nog wel even doen, die array is heel makkelijk te genereren met een C++ progje..
Geen idee hoe het zit met performance e.d. maar denk dat het wel mee zal vallen.. Hier is hoe het eruit ziet:
Afbeeldingslocatie: http://www.theforumisdown.com/uploadfiles/0103/widths.gif

En dit is de code (nogmaals vrij lelijk nog):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?
    $arrWidths = Array (
        10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
        10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
        4, 3, 5, 7, 7, 12, 9, 2, 4, 4, 5, 8, 4, 4, 4, 4,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 8, 8, 8, 7,
        13, 9, 9, 9, 9, 9, 8, 10, 9, 3, 6, 9, 7, 11, 9, 10,
        9, 10, 9, 9, 7, 9, 9, 13, 7, 9, 7, 4, 4, 4, 5, 7,
        4, 7, 7, 7, 7, 7, 3, 7, 7, 3, 3, 7, 3, 11, 7, 7,
        7, 7, 4, 7, 4, 7, 5, 9, 7, 7, 7, 4, 3, 4, 8, 10,
        7, 10, 3, 7, 4, 13, 7, 7, 4, 14, 9, 4, 13, 10, 7, 10,
        10, 3, 3, 4, 4, 5, 7, 13, 4, 13, 7, 4, 12, 10, 7, 9,
        4, 3, 7, 7, 7, 7, 3, 7, 4, 10, 4, 7, 8, 4, 10, 7,
        5, 7, 4, 4, 4, 7, 7, 4, 4, 4, 5, 7, 11, 11, 11, 8,
        9, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 3, 3, 3, 3,
        9, 9, 10, 10, 10, 10, 10, 8, 10, 9, 9, 9, 9, 9, 9, 9,
        7, 7, 7, 7, 7, 7, 12, 7, 7, 7, 7, 7, 3, 3, 3, 3,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7);

    $arrTexts = 
        Array(
        "Ik heb het volgende probleem:",
        "Ik heb een tabel met daarin titels van hoofdstukken.",
        "Nou heeft die tabel een beperkte breedte en wil ik het",
        "zo voor elkaar krijgen dat ik elke titel op 1 regel krijg",
        "(op 2 regels is echt niet mooi). Je kan het misschien",
        "het beste vergelijken met een menu.",
        "Nu heb ik het op dit moment in php zo gedaan dat ie elke",
        "titel na een x aantal tekens afkapt en er \"...\" achter zet",
        "(het is tevens ook een link en in de title tag van de link",
        "heb ik wel de volledige naam staan).",
        "Nu vind ik dit best een mooie oplossing, maar nu komt het",
        "probleem. Als ik het aantal tekens laat afstemmen als ik",
        "kijk naar bijvoorbeel hoeveel \"O\" 's er op die regel ",
        "kunnen dan vind ik dat ie sommige titels wel veel te snel",
        "afkapt (een \"i\" is nou eenmaal minderbreedt dan een \"O\").",
        "Hoe zouden jullie dit nou oplossen?",
        "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
        "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
        "............................................................................",
        "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||",
        "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");

    function fixedText($text, $size)
    {
        global $arrWidths;
        $chars = 0; 
        $curSize = 0;
        for ($i=0;$i<strlen($text);$i++)
        {
            $curSize += $arrWidths[ord($text[$i])];
            if ($curSize > $size)
                break;
            $chars++;
        }
        return substr($text, 0, $chars);
    }
?>
<p style='font-family:Arial;font-size:10pt'><? 
    foreach($arrTexts as $text)
    {
        echo fixedText($text, 150), '<br>'; 
    }
?></p>

[ Voor 8% gewijzigd door madwizard op 05-08-2003 01:11 ]

www.madwizard.org


Acties:
  • 0 Henk 'm!

  • bigtree
  • Registratie: Oktober 2000
  • Laatst online: 16-08 17:16
Ik ga voor de array-methode waarin je opslaat hoe breed elke letter is. (Laten we het vooral in P&W op willen lossen :P)

Op basis van die array kan je eenvoudig de breedte in pixels van een string voor een bepaalde puntgrootte van een bepaald lettertype berekenen. Enig 'nadeel' is dat je dus een array moet hebben met de breedte van tekens. Gelukkig kan je die met behulp van javascript en php genereren, dus zo wordt het weer een voordeel, aangezien het automatisch gaat en dus nauwkeurig.

(Het is wel een onwijze spoiler maar ik vond het een leuk probleem dus heb er een kwartiertje proggen tegenaan gegooid (;)))

Allereerst vond ik deze javascript code om de breedte van een string te meten:
code:
1
2
3
4
<span id="length">Blaaat</span> 
<script type="text/javascript"> 
  alert(document.getElementById('length').offsetWidth); 
</script>
Vervolgens dit in een loopje gezet om zo de breedtes voor een hele zwik tekens te berekenen (werkt alleen in IE volgens mij):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

    // bigtree's font length thingy
    // (c) 2003 bigtree@29a.nl
    
    $from_chr = 33;
    $to_chr = 128;
    
    for ($i = $from_chr; $i <= $to_chr; $i++) {
    
        ?><span id="length<?php echo $i; ?>"><?php echo htmlspecialchars(chr($i)); ?></span><BR>
        <?php
    
    }

    for ($i = $from_chr; $i <= $to_chr; $i++) {
    
        ?>
        
        <script type="text/javascript"> 
          document.write('$charwidths[<?php echo $i; ?>] = ' +
          document.getElementById('length<?php echo $i; ?>').offsetWidth + ';<BR>'); 
        </script>
        
        
        <?php
    
    }

?>
En dit is de functie om op basis van de hier uitgespuugde array de breedte van een string te berekenen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    function textlength($text = '') {
    
        $tmp_length = 0;
        global $charwidths;
        
        for ($i = 0; $i < strlen($text); $i++) {
            if (isset($charwidths[ord($text{$i})])) {
                $tmp_length += $charwidths[ord($text{$i})];
            }
        }
        
        return $tmp_length;
    
    }
Als we bijvoorbeeld het standaard lettertype (Times 12Pt) nemen, retourneert
PHP:
1
echo 'bigtree: ' . textlength('bigtree');
het volgende
code:
1
bigtree: 41 pixels
edit:
er wordt hier iemand op zijn wenken bediend... O-)

[ Voor 9% gewijzigd door bigtree op 05-08-2003 01:25 ]

Lekker woordenboek, als je niet eens weet dat vandalen met een 'n' is.


Acties:
  • 0 Henk 'm!

  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

bigtree: Je bent de breedte voor een spatie (32) vergeten, daardoor klopt ie niet helemaal. Voor de rest werkte ie wel goed volgens mij, weet niet of via javascript de meest nauwkeurige bepaling is maar het werkt :).

Liqued: Hier staat het programma dat ik gebruikte voor het bepalen van de karakter breedtes.. Het werkt met een windows API die de grootte teruggeeft per karakter, daar maakt ie een array van en geeft een php scriptje.
Script in actie (nu met puntje-puntje-puntje :)):
http://www.madwizard.org/temp/times10.php (times 10pt italic, 150 pixels, source hier)
http://www.madwizard.org/temp/comicsans.php (comic sans 20pts, 400 pixels)

[ Voor 4% gewijzigd door madwizard op 05-08-2003 21:14 ]

www.madwizard.org


Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb ooit eens in PHP het onderstaande scriptje gemaakt. Kan je dus ook het lettertype etc meegeven. Heb geen flauw idee of je er iets snels mee kan maken... misschien heb je er wat aan....

PHP:
1
2
$box = imageTTFbbox(8, 0, "/domains/naam.nl/public_html/www/fonts/verdana.ttf", $_POST['woordje']);
$breedte = round(($box[2] - $box[0])*0.91);


[edit]
Je kan er een soort van functie van maken denk ik waarin je een x aantal karakters ingooid en aan de hand daarvan bepaald hoeveel er nog bij mogen of er af moeten..

[ Voor 23% gewijzigd door Verwijderd op 05-08-2003 21:18 ]


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Je realiseert je wel dat dit verschilt per lettertype enzo? Lijkt me een pokkewerk voor bijv. een forum, om dat op elke pageload te moeten berekenen...

Vandaar dat ik liever een server-friendly oplossing in W&G style hiervoor zou kiezen ;)

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

Verwijderd

Ik zei niet voor niets dat ik vraagtekens had over de snelheid.... En ja voor de verschillende lettertypes zal je ff je ttf moeten uploaden... verder kan je alles instellen....

Als je een applicatie ontwikkeld waarbij er niet veel bezoekers tegelijkertijd gebruk van maken kan je er mooie dingen mee maken!

[ Voor 28% gewijzigd door Verwijderd op 05-08-2003 21:47 ]


Acties:
  • 0 Henk 'm!

  • bigtree
  • Registratie: Oktober 2000
  • Laatst online: 16-08 17:16
Grijze Vos schreef op 05 augustus 2003 @ 21:36:
Je realiseert je wel dat dit verschilt per lettertype enzo?
Er is natuurlijk ook wel een scriptje te bouwen dat in één keer 20 lettertypes in 10 verschillende puntgroottes kan uitrekenen. Die opslaan in een databaseje en je bent voorlopig klaar.
Lijkt me een pokkewerk voor bijv. een forum, om dat op elke pageload te moeten berekenen...

Vandaar dat ik liever een server-friendly oplossing in W&G style hiervoor zou kiezen ;)
Als je items uit een database komen, kan je de 'verkorte' titel makkelijk cachen. Hoef je het maar één keer te berekenen. Dat zou ik liever doen dan een stylesheet-oplossing, waar je bent overgeleverd aan de gratie van de browser/versie. ;)

Lekker woordenboek, als je niet eens weet dat vandalen met een 'n' is.

Pagina: 1