Как вам может быть известно, в библиотеке cl-cairo2 параметры текста задаются в виде:
(select-font-face "Arial" :normal :italic)
в библиотеке cl-gtk2 используется кошерная запись "Arial Italic 12"
в этой форме информация по тексту и хранится в файле с чертежом, но для отрисовки на экране было необходимо перегнать ее в вид удобный для cl-cairo2. Долгое время я ленился заниматься этой бытовухой, но тут случайно приспичило. Итак - что сделано:
Сперва наготовил функцию которая разобьет строку на отдельные слова (странно что я не нашел такую в готовом виде)
(defun split-by-one-space (string)
(loop for i = 0 then (1+ j)
as j = (position #\Space string :start i)
collect (subseq string i j)
while j))
Далее сам код
(defun gtkfont-to-cairofont (cd)
(cond ((= (length (getf cd :style)) 4)
(select-font-face
(car (split-by-one-space (getf cd :style)))
(or
(cond
((equal (caddr (split-by-one-space (getf cd :style))) "Bold") :bold))
:normal)
(or
(cond
((equal (cadr (split-by-one-space (getf cd :style))) "Italic") :italic))
:normal)))
((= (length (getf cd :style)) 3)
(if (equal (cadr (split-by-one-space (getf cd :style))) "Bold")
(select-font-face
(car (split-by-one-space (getf cd :style)))
:bold
:normal)
(select-font-face
(car (split-by-one-space (getf cd :style)))
:normal
:italic)))
((= (length (getf cd :style)) 2)
(select-font-face
(car (split-by-one-space (getf cd :style)))
:normal
:normal))))
(select-font-face "Arial" :normal :italic)
в библиотеке cl-gtk2 используется кошерная запись "Arial Italic 12"
в этой форме информация по тексту и хранится в файле с чертежом, но для отрисовки на экране было необходимо перегнать ее в вид удобный для cl-cairo2. Долгое время я ленился заниматься этой бытовухой, но тут случайно приспичило. Итак - что сделано:
Сперва наготовил функцию которая разобьет строку на отдельные слова (странно что я не нашел такую в готовом виде)
(defun split-by-one-space (string)
(loop for i = 0 then (1+ j)
as j = (position #\Space string :start i)
collect (subseq string i j)
while j))
Далее сам код
(defun gtkfont-to-cairofont (cd)
(cond ((= (length (getf cd :style)) 4)
(select-font-face
(car (split-by-one-space (getf cd :style)))
(or
(cond
((equal (caddr (split-by-one-space (getf cd :style))) "Bold") :bold))
:normal)
(or
(cond
((equal (cadr (split-by-one-space (getf cd :style))) "Italic") :italic))
:normal)))
((= (length (getf cd :style)) 3)
(if (equal (cadr (split-by-one-space (getf cd :style))) "Bold")
(select-font-face
(car (split-by-one-space (getf cd :style)))
:bold
:normal)
(select-font-face
(car (split-by-one-space (getf cd :style)))
:normal
:italic)))
((= (length (getf cd :style)) 2)
(select-font-face
(car (split-by-one-space (getf cd :style)))
:normal
:normal))))
Как видно я ветвил задачу по количеству элементов в готовом списке. Получилось это громоздко, но вполне работоспособно. О чем свидетельствует этот скрин:
Но не все так чисто - наклонный или жирный текст почему то отображается как обычный. Видимо в библиотеке cl-cairo2 опять произошли какие то изменения. Короче, кто ткнет носом тому поклон за науку))


> split-by-one-space
ОтветитьУдалитьОсобо не вникал, но здесь же можно (нужно) было заюзать split-sequence
хорошая функция
ОтветитьУдалитьвидать я опять велосипед построил
сейчас посмотрю кто из них быстрее работает
Омг! в этм случае придется тащить за собой зависимость в виде целой кучи тулзов
ОтветитьУдалитьdev-lisp/split-sequence
и все это ради одной лишь маленькой функции))
все таки применить малый велосипед получается более разумным
Заранее прошу прощение, за неглубокий анализ и возможную грубую ошибку, но вот это кажется странным:
ОтветитьУдалить(cond ((= (length (getf cd :style)) 4)
(select-font-face
(car (split-by-one-space (getf cd :style))) ...
мы проверяем что у нас в последовательности 4 элемента, если да, то вызываем ф-ию select-font-face, а перед этим вычисляем её аргумент разбивая последовательность(а именно строку), кстати из 4-ёх знаков. (че там разбивать то). А ниже вообще разбив. строка из 3-её знаков ... как-то подозрительно...
да и split-sequence мне тоже кажется более лучшим решением. Непонял насчёт кучи тулзов, split-sequence реализуется в одном файле.
Повторюсь, хоть split-sequence и хорош сам по себе, но тянуть зависимость ради одной функции не стану
ОтветитьУдалитьСтрока с параметрами может содержать как 4 слова "Arial Bold Italic 10", так и 3 "Arial Bold 10", и 2 "Arial 10". Строка разбивается каждый раз по новой для того чтобы не применять локальные переменные и не запутывать код.
Кстати, понял что код для реального применения не годится. Потому что я забыл о существовании шрифтов с названиями в несколько слов, такого типа "Times New Roman Bold Medium Italic 10"
> целой кучи тулзов
ОтветитьУдалить> тянуть зависимость ради одной функции не стану
Весь split-sequence состоит из функции split-sequence. Сам за собой зависимостей не тянет. По твоей логике, ты никогда его не заюзаешь, потому что в нём тока 1 функция, а ради одной функции ты зависимостей не таскаешь :)
Но ведь это же: (= (length (getf cd :style)) 4)
ОтветитьУдалитьпроверка на 4 буквы, разве нет?
Если честно то я не ожидал что одну функцию запакуют в виде отдельного пакета)) я считал что это целая библиотека по работе со строками
ОтветитьУдалитьа вот за (= (length (getf cd :style)) 4) очень благодарю. порой в упор не замечаю даже самых банальных ошибок. ушел чинить