七夕到了是不是該做點什麼了~
體驗地址
[2019-7-31 更新]
做了個包~~
composer require jc91715/lattice -vvv
use Jc91715\Lattice\Lattice;
$str="helloworld";
$lattice = new Lattice($str,5);
echo $lattice->getResult();
<?php
$font_width = 16; // 單字寬度
$font_height = 16; // 單字高度
$byteCount = $font_width * $font_height / 8;//一個點陣佔的位元組數
$str=iconv("utf-8","gb2312//IGNORE", "我是大是的大薩法fasf大多數");
$n=5;//每一行四個字
//所有字的字模
$dot = getDot($str,$byteCount);
/**
* $positions 平面座標系
* $sections 每一個字模在平面座標系中的點。(可移動每一個字模的位置)
* $spreadSections 所有字模在平面座標系中的點,是$sections的展開
*
*/
list($positions,$sections,$spreadSections) = getPositionsSections($dot,$byteCount,$n);
/**
* 輸出點陣html字串
*/
echo getOutHtml($positions,$sections,$spreadSections,$n);
/**
* 從字型檔中獲得每一個字的字模
* @param $str
* @param $byteCount
* @return string
*/
function getDot($str,$byteCount){
$dot='';
$fontFileName = './HZK16';//字型檔名字
$fp = fopen($fontFileName, "rb");
for ($i=0;$i<strlen($str);$i++){
if(ord($str[$i])<160){//非漢字
$location=(ord($str{$i}) + 156-1) * $byteCount;
}else {//漢字
$qh = ord($str[$i]) - 32 - 128;//區碼
$wh = ord($str[++$i]) - 32 - 128;//位碼
$location = (94 * ($qh - 1) + ($wh - 1)) * $byteCount; /* 計算漢字字模在檔案中的位置 */
}
fseek($fp, $location, SEEK_SET);//定位到漢字或字母指標開始的地方
$dot.= fread($fp, $byteCount);//讀取32位元組的長度,一個位元組8位,一行依次放兩個位元組組成16*16的點陣
}
fclose($fp);
return $dot;
}
/**
* 建平面按座標系。並把每一區塊用平面座標系表示
* @param $dot
* @param $byteCount
* @param $n
* @return array
*/
function getPositionsSections($dot,$byteCount,$n){
$count= strlen($dot)/$byteCount;//多少個字
$positions=[];
$sections =[];
$sectionCount=$count;
for ($i=0;$i<$sectionCount;$i++){
$sections[]=[];
}
$yHeight=(intval($count/$n)*16+16);
$xWeight=16*$n;
for ($i=0;$i<$yHeight;$i++){
for ($j=0;$j<$xWeight;$j++){
$positions []=[$j,$i];
$x=ceil(($j+1)/16);
$y=ceil(($i+1)/16);
$y--;
$x--;
$sections[(($y)*$n+$x)][] = [$j,$i];
}
}
for ($b=0;$b<$count;$b++){//每一個字佔用的點陣
$str = substr($dot,($b)*32,$byteCount);//第幾個字
$dot_string='';
for ($c = 0; $c < $byteCount; $c++){
$dot_string .= sprintf("%08b", ord($str[$c]));
if ($c % 2 == 1) {
for($a=0;$a<strlen($dot_string);$a++){
if($dot_string[$a]){//和平面座標系關聯起來
$sections[$b][intval(16*floor($c/2)+$a)][]=1;
}
}
$dot_string = '';
}
}
}
$spreadSections=[];//每一個字塊的的點展開到陣列中
foreach ($sections as $section){
$spreadSections = array_merge($spreadSections,$section);
}
return [$positions,$sections,$spreadSections,$count,$sectionCount];
}
function getOutHtml($positions,$sections,$spreadSections,$n){
$str="<html><body><table border='1' width='100%' style='text-align: center'>";
foreach (array_chunk($positions,16*$n) as $row){
$str.=getOutRow($row,$sections,$spreadSections);
}
$str .= "</table></body>
</html>";
return $str;
}
function getOutRow($row,$sections,$spreadSections){
$str="<tr>";
foreach ($row as $td) {
if (!in_array($td,$spreadSections)){//不在平面座標系中說明這個位置是一個點
$str .= "<td style='color: white;background-color: red;'>O</td>";
}else {
$str .= "<td>O</td>";
}
}
$str.="<tr>";
return $str;
}