— Created 2017-12-12 by Takaaki Naganoya
— Modified 2019-03-29 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
property NSFont : a reference to current application’s NSFont
property NSUUID : a reference to current application’s NSUUID
property NSColor : a reference to current application’s NSColor
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSPredicate : a reference to current application’s NSPredicate
property NSDictionary : a reference to current application’s NSDictionary
property NSBezierPath : a reference to current application’s NSBezierPath
property NSColorSpace : a reference to current application’s NSColorSpace
property NSPNGFileType : a reference to current application’s NSPNGFileType
property NSFontManager : a reference to current application’s NSFontManager
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSMutableDictionary : a reference to current application’s NSMutableDictionary
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSKernAttributeName : a reference to current application’s NSKernAttributeName
property NSMutableParagraphStyle : a reference to current application’s NSMutableParagraphStyle
property NSLigatureAttributeName : a reference to current application’s NSLigatureAttributeName
property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString
property NSUnderlineStyleAttributeName : a reference to current application’s NSUnderlineStyleAttributeName
property NSParagraphStyleAttributeName : a reference to current application’s NSParagraphStyleAttributeName
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName
property fillCharList : {}
property fillCharCounter : 1
set aString to "Love"
set bString to "hate"
set hanaSize to 24
set thisFont to selectAFont(first character of aString) of me
if thisFont = false then return –Cancel
–花文字文字列を作成
set fRes to getEnglishHanamojiStr(hanaSize, thisFont, aString, bString, 0.7, true, true) of me
makeNewDocument given parameter:fRes
–花文字文字列を計算して返す
on getEnglishHanamojiStr(aFontSize as real, aFontName as string, aString as string, fillString as string, aThread as real, incFontName as boolean, invertF as boolean)
set my fillCharList to characters of fillString
set my fillCharCounter to 1
–指定文字コードが指定フォント中に存在するかチェック
repeat with i in (characters of aString)
set fRes to retGlyphsInFont(aFontName, id of i) of me
if fRes = false then return false
end repeat
set aThreadShould to 768 * aThread
if (chkMultiByteChar(first character of aString) of me) = false then
set spaceChar to string id 12288 –全角スペース(UTF-16)
else
set spaceChar to string id 32 –半角スペース
end if
set fillColor to NSColor’s whiteColor –塗り色
set bString to aString & " " –処理内容の帳尻合わせ(そのままだと右端が欠けるのでスペースを入れた)
set anAssrStr to makeRTFfromParameters(bString, aFontName, aFontSize, -2, (aFontSize * 1.2)) of me
set aSize to anAssrStr’s |size|()
if class of aSize = record then
set attrStrWidth to width of aSize
set attrStrHeight to height of aSize
else if class of aSize = list then –macOS 10.13.xのバグ回避
copy aSize to {attrStrWidth, attrStrHeight}
end if
set {xPos, yPos} to {0, 0}
set tmpImg1 to makeImageWithFilledColor(attrStrWidth, attrStrHeight, fillColor) of me
set tmpImg2 to drawAttributedStringsOnImage(tmpImg1, anAssrStr, xPos, yPos) of me
set aRawimg to NSBitmapImageRep’s imageRepWithData:(tmpImg2’s TIFFRepresentation())
–画像から順次指定座標の色データを拾って花文字listに反映
set strList to {}
repeat with y from 1 to attrStrHeight – 1
set strListX to {}
repeat with x from 0 to attrStrWidth – 1
set tmpCol to getColorFromRawImage(aRawimg, x, y) of me
if invertF = false then
–通常描画(invert = false)時
if tmpCol is not equal to false then
if tmpCol is not equal to {255, 255, 255} then
copy tmpCol to {tmpR, tmpG, tmpB}
if (tmpR + tmpG + tmpB) < aThreadShould then
set the end of strListX to getChar() of me
else
set the end of strListX to spaceChar
end if
else
set the end of strListX to spaceChar
end if
end if
else
–白黒反転(invert = true)時
if tmpCol is not equal to false then
if tmpCol is not equal to {255, 255, 255} then
copy tmpCol to {tmpR, tmpG, tmpB}
if (tmpR + tmpG + tmpB) < aThreadShould then
set the end of strListX to spaceChar
else
set the end of strListX to getChar() of me
end if
else
set the end of strListX to getChar() of me
end if
end if
end if
end repeat
set the end of strList to strListX
end repeat
–2D List→Text
set aRes to list2dToStringByUsingDelimiters(strList, "", return) of me
if incFontName = true then
set fName to getDisplayedNameOfFont(aFontName) of me
set aRes to "Font=" & fName & return & return & aRes
end if
return aRes
end getEnglishHanamojiStr
on getChar()
set retChar to item (my fillCharCounter) of (my fillCharList)
if (my fillCharCounter) = length of (my fillCharList) then
set (my fillCharCounter) to 1
else
set (my fillCharCounter) to (my fillCharCounter) + 1
end if
return retChar
end getChar
–指定Raw画像中の指定座標のピクセルの色をRGBで取り出す
on getColorFromRawImage(aRawimg, x as real, y as real)
set aRatio to getImageRatio() of me –Retina Display対応
set origColor to (aRawimg’s colorAtX:(x * aRatio) y:(y * aRatio))
set srgbColSpace to NSColorSpace’s deviceRGBColorSpace
if srgbColSpace = missing value then return false
set aColor to (origColor’s colorUsingColorSpace:srgbColSpace)
set aRed to (aColor’s redComponent()) * 255
set aGreen to (aColor’s greenComponent()) * 255
set aBlue to (aColor’s blueComponent()) * 255
return {aRed as integer, aGreen as integer, aBlue as integer}
end getColorFromRawImage
–画像のうえに指定のスタイル付きテキストを描画して画像を返す
on drawAttributedStringsOnImage(anImage, anAssrStr, xPos as real, yPos as real)
anImage’s lockFocus()
anAssrStr’s drawAtPoint:(current application’s NSMakePoint(xPos, yPos))
anImage’s unlockFocus()
return anImage
end drawAttributedStringsOnImage
–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aKerning as real, aLineSpacing as real)
set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize
set aKey1 to (NSFontAttributeName)
set aVal2 to NSColor’s blackColor()
set aKey2 to (NSForegroundColorAttributeName)
set aVal3 to aKerning
set akey3 to (NSKernAttributeName)
set aVal4 to 0
set akey4 to (NSUnderlineStyleAttributeName)
set aVal5 to 2 –all ligature ON
set akey5 to (NSLigatureAttributeName)
set aParagraphStyle to NSMutableParagraphStyle’s alloc()’s init()
aParagraphStyle’s setMinimumLineHeight:(aLineSpacing)
aParagraphStyle’s setMaximumLineHeight:(aLineSpacing)
set akey7 to (NSParagraphStyleAttributeName)
set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey7}
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aParagraphStyle}
set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
return attrStr
end makeRTFfromParameters
–指定サイズの画像を作成し、背景を指定色で塗る
on makeImageWithFilledColor(aWidth as real, aHeight as real, fillColor)
set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight))
set aRatio to getImageRatio() of me –Retina Display対応
anImage’s lockFocus()
set theRect to {{x:0, y:0}, {width:aWidth * aRatio, height:aHeight * aRatio}}
set theNSBezierPath to NSBezierPath’s bezierPath
theNSBezierPath’s appendBezierPathWithRect:theRect
fillColor’s |set|()
theNSBezierPath’s fill()
anImage’s unlockFocus()
return anImage
end makeImageWithFilledColor
–2D Listをアイテム間および行間のデリミタを個別に指定してテキスト変換
on list2dToStringByUsingDelimiters(aList as list, itemDelimiter, lineDelimiter)
set outList to {}
repeat with i in aList
set aStr to listToStringUsingTextItemDelimiter(i, itemDelimiter) of me
set the end of outList to aStr
end repeat
set bStr to listToStringUsingTextItemDelimiter(outList, lineDelimiter) of me
return bStr
end list2dToStringByUsingDelimiters
on listToStringUsingTextItemDelimiter(sourceList as list, textItemDelimiter)
set CocoaArray to NSArray’s arrayWithArray:sourceList
set CocoaString to CocoaArray’s componentsJoinedByString:textItemDelimiter
return (CocoaString as string)
end listToStringUsingTextItemDelimiter
–ユーザー環境にインストールされているすべてのフォントのPostScript名とグリフ数を返す
on getEveryFontPSNameANdGlyphsNum(aStr)
set aFontList to NSFontManager’s sharedFontManager()’s availableFonts()
set thePred to NSPredicate’s predicateWithFormat:"NOT SELF BEGINSWITH ’.’"
set aFontList to (aFontList’s filteredArrayUsingPredicate:thePred) as list
set aList to {}
repeat with i in aFontList
set aName to contents of i
set aNum to countNumberOfGlyphsInFont(aName) of me
set dName to getDisplayedNameOfFont(aName) of me
set fRes to retGlyphsInFont(aName, id of aStr) of me
if fRes = true then
set the end of aList to {fontName:aName, fontNum:aNum, dispName:dName}
end if
end repeat
return aList
end getEveryFontPSNameANdGlyphsNum
–指定Postscript名称のフォントに定義されている文字数を数えて返す
on countNumberOfGlyphsInFont(fontName as string)
set aFont to NSFont’s fontWithName:fontName |size|:9.0
if aFont = missing value then return false
set aProp to aFont’s numberOfGlyphs()
return aProp as number
end countNumberOfGlyphsInFont
–フォントのPostScript NameからDisplayed Nameを取得
on getDisplayedNameOfFont(aName as string)
set aFont to NSFont’s fontWithName:aName |size|:9.0
set aDispName to (aFont’s displayName()) as string
return aDispName
end getDisplayedNameOfFont
–全角文字が存在するか
on chkMultiByteChar(checkString as string)
set aStr to NSString’s stringWithString:checkString
set aRes to aStr’s canBeConvertedToEncoding:(current application’s NSASCIIStringEncoding)
return (aRes as boolean)
end chkMultiByteChar
–指定名称のフォントに指定の文字コードが含まれているかチェック
on retGlyphsInFont(fontName as string, strCode as integer)
set aFont to NSFont’s fontWithName:fontName |size|:24.0
if aFont = missing value then return false
set aSet to aFont’s coveredCharacterSet()
set aRes to (aSet’s characterIsMember:strCode) as boolean
return aRes as list of string or string –as anything
end retGlyphsInFont
on selectAFont(aString)
set fRes to getEveryFontPSNameANdGlyphsNum(aString) of me
set theArray to NSArray’s arrayWithArray:fRes
set thePred to NSPredicate’s predicateWithFormat:"fontNum > 10000"
set bArray to ((theArray’s filteredArrayUsingPredicate:thePred)’s valueForKeyPath:"dispName") as list
set thisFont to choose from list bArray
return thisFont
end selectAFont
–Retina Display対応ルーチン
on getImageRatio()
set retinaF to detectRetinaDisplay() of me
if retinaF = true then
return 2.0 as real
else
return 1.0 as real
end if
end getImageRatio
on detectRetinaDisplay()
set dispList to current application’s NSScreen’s screens()
set retinaF to false
repeat with i in dispList
set j to contents of i
set aDepth to j’s backingScaleFactor()
if aDepth > 1.0 then
set retinaF to true
end if
end repeat
return retinaF
end detectRetinaDisplay