Author Topic: True spacing for letters  (Read 6660 times)

0 Members and 1 Guest are viewing this topic.

SomeCallMeDave

  • Guest
Re: True spacing for letters
« Reply #15 on: November 10, 2006, 08:13:25 AM »
Here is some quick code I put together to take a given text style and height and create a list of the individual character widths and that character's separation distance.  The list is of the form (character singleWidth SeparationDist)

Taking the resulting list and a string of text,  one may be able to calculate the length of a sub-string.

I don't know if this helps, or is even applicable to the problem at hand,  but it was an interesting exercise  And attempts to address this
Does anyone know how to get the true spacing for letters from looking at the font file?

Code: [Select]
(defun charWidth(pStyle pHeight / StartChar EndChar CurrChar WidthList BasePt BaseHt BaseTextEnt
                                TestEnt TestList 10Pt 11Pt SingleDist DoubleDist SepDist)
    (setq StartChar 32
          EndChar 126
          CurrChar StartChar
          WidthList nil
          BasePt (list 0 0 0)
          BaseHt pHeight
    )
    (repeat (- EndChar StartChar)
         (setq BaseTextEnt (list
                     '(0 . "TEXT")
                     '(100 . "AcDbEntity")
                     '(67 . 0)
                     '(410 . "Model")
                      (cons 8 "0" )
                     '(100 . "AcDbText")
                      (cons 10 BasePt)
                      (cons 40 BaseHt)
                      (cons 1 (chr currChar))
                      (cons 7 pStyle)
                     '(71 . 0)
                     '(72 . 2)
                      (cons 11 BasePt)
                     '(73 . 0)                 
               );list
             );setq 
                                       
         (entmake BaseTextEnt)
         (setq TestEnt (entlast)
               TestList (entget TestEnt)
               10Pt (cdr (assoc 10 TestList))
               11Pt (cdr (assoc 11 TestList))
               SingleDist (distance 10Pt 11Pt)
         )
         (entdel TestEnt)
         (setq TestList (subst (cons 1 (strcat (chr currChar) (chr currChar))) (assoc 1 TestList) TestList))
         (entmake TestList)
         (setq TestEnt (entlast)
               TestList (entget TestEnt)
               10Pt (cdr (assoc 10 TestList))
               11Pt (cdr (assoc 11 TestList))
               DoubleDist (distance 10Pt 11Pt)
               SepDist (- DoubleDist (* 2 SingleDist))
               WidthList (append WidthList (list (list CurrChar SingleDist SepDist)))
               CurrChar (+ CurrChar 1)
         )
         (entDel TestEnt)         
     )   
         
         

     WidthList
)

(defun c:TestCharWidth( / e1 e1List currStyle currHt DataList)
   (setq e1 (car (entsel "\nPick Text "))
         e1List (entget e1)
         currStyle (cdr (assoc 7 e1List))
         currHt (cdr (assoc 40 e1List))
         DataList (charWidth currStyle currHt)
    )     
)

(defun c:TestChar( / e1 e1List currStyle currHt DataList)
   (setq e1 (car (entsel "\nPick Text "))
         e1List (entget e1)
         Test10 (cdr (assoc 10 e1List))
         Test11 (cdr (assoc 11 e1List))
         TestDist (distance Test10 Test11)
    )     
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: True spacing for letters
« Reply #16 on: November 10, 2006, 08:32:34 AM »
Thats a good idea to use "justify Right" to get the character width.

Still may be a little time consuming if there are many fonts & text heights.

Using your idea I would do it this way:

Pass the routine a string to test
Look in a global list to see if the style has already been processed

Else process all the characters getting the widths
then calculate the height to width ratio & save in the global list

to process the string, use the height times the ratio to get the current width
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: True spacing for letters
« Reply #17 on: November 10, 2006, 08:37:34 AM »
Just checking & the method does not revel the space between characters.
So you would have to check a 2 character string & subtract there widths to get the
separation space width.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SomeCallMeDave

  • Guest
Re: True spacing for letters
« Reply #18 on: November 10, 2006, 08:44:36 AM »
CAB,
The function charwidth does check a 2 character string and the overall list includes the separation.  But it doesn't take into account any changes to the width factor other than those that may be in the style definition.

I was thinking also that the user would probably build a global list and check against it,  but the routine doesn't take very long to run.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: True spacing for letters
« Reply #19 on: November 10, 2006, 09:02:25 AM »
OK, I see it as I look more closely at the code.
Thanks
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: True spacing for letters
« Reply #20 on: November 10, 2006, 09:51:28 AM »
Well this seems to work with Dave's routine. Good job Dave!
This is a ROUGH draft. Aside from the speed issue, the pick box may need to be enlarged
for the nentselp to work better.

Code: [Select]
(defun c:test (/       CHAR    CHT     CSTYLE  DIS     ELST    ENT     IDX
               LEFTLST LEFTSTR P1      PT      RIGHTSTR        STRLST  WID
               WIDLIST
              )
  (if
    (and
      (setq pt (getpoint "\nPick point to break text."))
      (setq ent (nentselp pt))
    )
     (progn
       (setq elst (entget (car ent)))
       (setq p1     (cdr (assoc 10 elst))
             cStyle (cdr (assoc 7 elst))
             cHt    (cdr (assoc 40 elst))
       )
       (setq dis (distance p1 pt))
       (setq widlist (charWidth cStyle cHt))
       (setq wid    0
             idx    -1
             strlst (vl-string->list (cdr (assoc 1 elst)))
       )
       (while
         (progn
           (setq char (nth (setq idx (1+ idx)) strlst))
           (setq wid (+ wid (apply '+ (cdr (assoc char widlist)))))
           (setq leftlst (cons char leftlst))
           (<= wid dis)
         )
       )
       (print (setq leftstr (vl-list->string (reverse leftlst))))
       (print (setq rightstr (substr (cdr (assoc 1 elst)) (1+(strlen leftstr)))))
     )
  )
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: True spacing for letters
« Reply #21 on: November 10, 2006, 11:20:21 AM »
Thanks Dave and Alan!  I think that is the best way to go.  Maybe store the information in a dictionary within the drawing for easier use.  I will see what I can come up with later today.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.