2011-07-17 13 views
5

Generuję obraz SVG w python (czysty, nie ma jeszcze zewnętrznych bibliotek). Chcę wiedzieć, jaki będzie rozmiar elementu tekstowego, zanim go właściwie umieszczę. Jakiś dobry pomysł, jak to zrobić? Sprawdziłem pysvg biblioteki, ale nic nie widziałem jak getTextSize()uzyskać rozmiar tekstu svg w python

Odpowiedz

1

To może być dość skomplikowana być. Na początek musisz zapoznać się z chapter on text specyfikacji SVG. Zakładając, że chcesz uzyskać szerokość zwykłego text elementów, a nie textpath elementy, przynajmniej trzeba by:

  • Analizować font selection properties, spacing properties i odczytać xml:space attibute, a także właściwość writing-mode (może też być górą-dołem zamiast tylko od lewej do prawej i od prawej do lewej).
  • W oparciu o powyższe, otwórz właściwą czcionkę i odczytaj dane glifów, a następnie wyodrębnij szerokości i wysokości glifów w ciągu tekstowym. Samo znalezienie czcionki może być dużym zadaniem, gdy widzisz wiele miejsc, w których ukrywają się pliki czcionek.
  • (opcjonalnie) Przejrzyj ciąg znaków pod kątem możliwego ligatures (w zależności od języka) i zastąp je poprawnym glifem, jeśli istnieje w czcionce.
  • Dodaj szerokości dla wszystkich znaków i spacji, przy czym te ostatnie zależą od właściwości odstępów i (opcjonalnie) możliwych par kerning.

Możliwe rozwiązanie polegałoby na użyciu biblioteki pango. Możesz znaleźć dla niego wiązania Pythona w py-gtk. Niestety, z wyjątkiem niektórych examples, dokumentacji powiązań Pythona jest bardzo mało. Ale zajmie się szczegółami ładowania czcionek i określeniem zakresu wartości Layout.

Innym sposobem jest zbadanie renderera SVG w przeglądarce. Ale np. obsługa tekstu SVG w Firefoksie to limited.

także pouczające jest zbadanie, jak TeX robi, zwłaszcza concept (pdf) z skrzynek (na listach) i kleju (dla odstępu).

1

Miałem dokładnie ten sam problem, ale miałem czcionkę o zmiennej szerokości. Rozwiązałem go, biorąc element tekstowy (poprawną czcionkę i treść), który chciałem, napisałem do pliku svg, a ja użyłem Inkscape zainstalowanego na moim komputerze do , renderując rysunek do tymczasowego pliku png. Następnie odczytałem wymiary pliku png (wyodrębnionego z nagłówka), usunąłem pliki temp svg i png i wykorzystałem wynik, aby umieścić tekst tam, gdzie chciałem i elementy wokół niego.

Zauważyłem, że renderowanie do rysunku przy użyciu DPI 90 dawało mi dokładnie taką liczbę, jakiej potrzebowałem, lub numery natywne używane w svgwrite jako całości. -D jest flagą do użycia, tak że renderowany jest tylko element ciągnący, tj. Tekst.

os.cmd(/cygdrive/c/Program\ Files\ \(x86\)/Inkscape/inkscape.exe -f work_temp.svg -e work_temp.png -d 90 -D) 

użyłem tych funkcji, aby wyodrębnić numery PNG, znaleźli się w tym link, trzeba pamiętać, kopalnia jest poprawione nieznacznie python3 (nadal pracuje w python2)

def is_png(data): 
    return (data[:8] == b'\x89PNG\r\n\x1a\n'and (data[12:16] == b'IHDR')) 

def get_image_info(data): 
    if is_png(data): 
     w, h = struct.unpack('>LL', data[16:24]) 
     width = int(w) 
     height = int(h) 
    else: 
     raise Exception('not a png image') 
    return width, height 

if __name__ == '__main__': 
    with open('foo.png', 'rb') as f: 
     data = f.read() 

    print is_png(data) 
    print get_image_info(data) 

Nadszedł niezgrabne, ale to działało