书名:JQuery Cookbook
作者:Lindley Cody
出版:O’Reilly Media 2009
ISBN:0596159773
格式:PDF;3.7MB;476页
下载链接/download link:
easy-share
书名:JQuery Cookbook
作者:Lindley Cody
出版:O’Reilly Media 2009
ISBN:0596159773
格式:PDF;3.7MB;476页
下载链接/download link:
easy-share
转载:http://www.cnblogs.com/nuaalfm/archive/2009/11/27/1612027.html
FCKEditor是一款强大的在线编辑器,简单实用,多浏览器兼容,免费开源,应用十分广泛,据他的官方网站上称有三百多万的下载量,而且无数的 知名大公司正在使用它。所以FCKEditor是很值得信赖的,现在 FCKeditor项目已转向下一代版本命名CKEditor的产品开发,基本上采用Fckeditor并对部分进行了重新设计和采用新技术以改善结构, 性能更好扩展性更强。下面我们来介绍一个这两个编辑器,对于FCKEditor我们只讲一下在ASP.NET MVC中的用法其配置可以参考官方文档。
一、FCKEditor使用:
1、FCKEditor在ASP.NET MVC中的应用:
首先到http://ckeditor.com/download下载FCKeditor 2.6.5(我下载的时候报地址暂时有问题,但FCKEditor网上保有量很多,可以任意下载一个),将下载好的文件解压缩然后拷贝到你项目的Content文件夹下:
View
Controller:
这里要注意[ValidateInput(false)]特性,它的目的是为了防止在提交时报“检测到有潜在危险的客户端输入值”,另外这里还有 个奇怪的现象就是这个View不能在Index.aspx中,在Index.aspx即使使用了[ValidateInput(false)]特性还是会 报错,换个新View就没这个问题了,不知道为什么?
2、Helper版
为了让大家使用的更简单,我写了个Helper版,大家参考下:
View:
二、CKEditor使用
1、CKEditor在ASP.NET MVC中的应用:
首先到http://ckeditor.com/download下载CKEditor。
CKEditor在ASP.NET MVC的使用就相当的简单了,只需要在脚本中执行CKEDITOR.replace(id);id为你需要拥有编辑功能的textarea的id。
View:
结果:
2、CKEditor配置:
CKEditor配置也很容易, 使用CKEDITOR.replace方法,根据不同的参数来应用不同的配置,例如
得到的结果:
其他配置可以参考官方文档。同时_samples文件夹中也有大量例子可供参考。
3、CKEditor瘦身:
如果你觉得整个编辑器太大,你可以删除文件。
例如把_samples、_source、文件夹删除,进入lang文件目录,保留en.js、zh.js、zh-cn.js三个文件,其余的语言文件如果你用不到,可以删除。
三、参考
http://www.ff-bb.cn/logs/46479725.html
http://www.codeproject.com/KB/aspnet/fckeditor.aspx
我的ASP.NET MVC实践系列
ASP.NET MVC实践系列7-Grid实现(下-利用Contrib实现)
ASP.NET MVC实践系列8-对查询后分页处理的解决方案
其他:
转载:http://www.cnblogs.com/nuaalfm/archive/2009/11/26/1611420.html
最早接触单元测试是看了极限编程相关资料里边讲的测试驱动开发,然后下载了Nunit研究了一下,但并没产生多大的触动,因为那个时候做的都是些时 间紧任务重的事情,对于单元测试的直接感觉就是有可能比较费时间。直到看了《敏捷软件开发:原则、模式与实践》,里边那个保龄球计分程序很精彩,让我知道 了保龄球原来是这么计分的,更重要的是让我认识到测试驱动编程原来这样有意义,并且其实并不浪费时间(至于测试驱动编程到底有意义在哪里,我这里就不说 了,大家可以参阅Kent的《测试驱动开发》,Robert C. Martin的《敏捷软件开发:原则、模式与实践》,http://www.ibm.com/developerworks/cn/linux/l-tdd/,http://www.ibm.com/developerworks/cn/java/j-xp042203/等)。在webform中对web层的逻辑很难做单元测试(当然我们可以利用mvp模式(参考:http://www.cnblogs.com/bluewater/archive/2006/12/11/589214.html#1219888) 来分解web层逻辑,但因为没有框架的支持,并且实现起来也不是很简单,也不是特别好理解,所以应用并不广泛)。ASP.NET MVC很好的解决了测试web逻辑的问题,可测试性也变成了ASP.NET MVC的优势之一。下面我们就来介绍一下如何在ASP.NET MVC中进行单元测试。
一、测试路由器:
我们首先利用mvc的模板创建一个解决方案,我们可以在Gloabal.asax.cs文件中发现如下代码
下面我们就为这段代码写一个单元测试(如果对路由还不清楚请参见:ASP.NET MVC实践系列1-UrlRouting )
下面我们解释一下上面的代码
RouteCollection routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
这两行的意思是将routes按照默认路由代码中的格式生成相应的路由。
var httpContextMock = new Mock<HttpContextBase>();
httpContextMock.Setup(c => c.Request.AppRelativeCurrentExecutionFilePath).Returns("~/Home/Index");
这两行的意思是创建一个HttpContextBase的mock类,这里我们使用的是MoQ框架来生成mock类(参见:MoQ(基于.net3.5,C#3.0的mock框架)简单介绍 )。
RouteData routeData = routes.GetRouteData(httpContextMock.Object);
这行的意思是从routes中获得路由数据,为下边断言路由中的内容作准备。
Assert.AreEqual("Home", routeData.Values["Controller"]);
Assert.AreEqual("Index", routeData.Values["action"]);
Assert.AreEqual("", routeData.Values["id"]);
这三行分别验证了路由中生成的Controller,action,id的正确性。
二、测试Controller与Action
1、测试ViewData
我们先来看一下ASP.NET MVC的默认模板中的测试代码:
我们可以在测试代码中对viewData的内容进行验证,一般并不推荐使用弱类型的viewData来进行传递数据,下面我们来看一下如何来测试viewModel中的内容。
2、测试RedirectToAction:
三、测试View Helpers
我们常常会把一些牵扯到逻辑的View代码写到Helper中,所以测试Helper非常有意义,我们先写一个简单的Helper
这个Helper的完成的工作是将输入的集合数据分解然后按列表输出。
4-9行都是为实例化HtmlHelper做准备的。
四、参考
《Professional ASP.NET MVC 1.0》
《ProASP.NET MVCFramework》
http://msdn.microsoft.com/en-us/magazine/dd942838.aspx
http://www.henrycordes.nl/post/2008/02/MVC-Framework-and-Unit-Test.aspx
我的ASP.NET MVC实践系列
ASP.NET MVC实践系列7-Grid实现(下-利用Contrib实现)
ASP.NET MVC实践系列8-对查询后分页处理的解决方案
其他:
转载:http://www.SEOwindows.com/SEOjq/200908/135.html
我们常常在GOOGLE或百度中用site指令的时候,会发现在结果最底部会出现“……我们省略了一些内容相似的条目,点击这里可以看到所有搜索结果”。
为什么会出现这种情况呢,最大可能就是被隐藏网页的相似度太高。
之前GOOGLE存在“补充材料”的时候,相似页面就很容易被Google贴上“补充材料”的标签。“补充材料”页的产生还有其他方面的因素,例如描述等。只不过,相似页面也是因素之一。
相似页面的优化,在SEO优化的工作当中,也是一个需要注意的细节。相似页面的清理和优化,可能主要涉及到网页设计人员。相似页面的产生,主要是因为这类页面的主体内容比较少,一些比较常规的辅助内容比较多。从而形成相似页面,这类页面在搜索引擎看来,价值性不高。
相似页面在网站整体的网页结构当中,可能是处在网页价值的末端。就是不太重要的网页,也很难获得搜索引擎的排名。
相似页面的形成
在每个网页中,正文内容必须在网页全部内容当中,占据比较重要或者比较大的比例。一般来说,正文在整张网页当中,所占比例只有20%-30%的时候,那很容易就形成一张相似页面。
主体内容在网页中的重要性
网页的正文就是网页的核心内容,网站管理者不应该为了更新网站或者方便,随便的写几句话就作为网站的原创内容来更新到网站。
网页的正文内容,文字不应该少于500字。字数太少,搜索引擎分析出网页的主题。分析不出网页主题,也就不利于网页的搜索引擎排名。
相似页面对网站的影响
相似页面过多的话,会稀释网站质量,包括权重、PR、链接等。从而影响到网站整体在搜索引擎上的表现,例如长尾关键词的排名表现的不理想等。比较严重的惩罚是认为网站管理员有SEOSPAM行为,对此类网页给予不收录或者降权等。
如何优化相似页面:
1.防止正文内容过少,这是最好防止产生相似页面的技巧之一;
2.让搜索引擎的蜘蛛优先抓到正文;
3.减少网页中不必要的内容结构。
网站内部优化其实就是把不必要的东西去除或者改善不好的内容。在网站优化中,应该尽量避免出现过多的相似页面。大家日常的更新网站内容的时候应该注意内容篇幅,看看正文是否能够说明页面主题。
转载:http://www.joyinweb.cn/html/baidu/2009/0922/826.html
反向链接是百度优化里常提到的说法,是SEO的第二要素,大多非专业人士可能不太熟悉,反向链接的一些指标也反应网站的健康状况,下面详细认识一下反向链接。
一、反向链接的定义
反向链接英文是:BackLinks,或Back-Links,又称为导入链接(incominglinks)。反向链接其实就是在目标文档内部进行声 明。换言之,常规链接在文档A中标明“指向文档B”,而反向链接则在文档B中要求“使文档A指向我”。反向链接是SEO的第二要素,重要性毋庸置疑。网络 上流传很多增加反向链接的10种方法、66种方法、101种方法,更有很多群建、群发的“黑帽”软件在流传,这里不做过多讨论。
二、反向链接的原则
1、时间原则
2008新版seo方程式SEO=∫Clock=∫C1+L2+K3+O4,之所以采用高等数学里积分的概念,是认为seo的时间原则是非常重要的,特别是对于反向链接的建设,尤为重要。
增加反向链接是一个长期的积累过程,要循序渐进、一步一步来;如果在短时间内迅速增加了超乎寻常的反向链接数,很容易遭到搜索引擎的特别处理(沙盒效应),seo效果适得其反,自然无法获得好的搜索排名。
2、数量原则
在遵循时间原则的基础上,反向链接数量自然多多益善。正所谓“广种薄收”,“不积小流,无以成江海”,茫茫网海,一分耕耘一分收获。
3、质量原则
网站长久持续获得好的排名,反向链接的质量比数量更为重要。何谓高质量的反向链接?链接导入页面高Pr值和相关性决定了反向链接的质量。比如,你的网站是 seo相关的主题,那么来源于seo排名前10位的网站的导入链接一定是高质量的;来源于一篇seo相关文章的导入链接也一定是高质量的。但是,高质量的 反向链接是可遇不可求的,虽然一个高质量的反向链接抵得上几十个甚至上百个垃圾反向链接,但是在无法获得高质量反向链接的情况下,那就遵循数量原则。
4、位置原则
其实位置原则是质量原则的一个补充,因为容易忽视且重要性不亚于数量和质量原则,所以特别需要重视。所谓位置,指的是反向链接在导入链接页面的具体位置。 搜索引擎抓取页面的时候会给不同区域的内容给与不同的权重,一般上、左区域权重高、下(尾)权重低。因此,反向链接出现在导入页面不同的位置会有不同的投 票分数,建议:
(1)如果有可能,那就让反向链接出现在导入页面的头部
(2)如果有可能,那就让反向链接出现在导入页面的左侧
(3)上述方法都不可能,那就让你的反向链接出现在内容区域的前面,相关性高的内容区域靠前的反向链接对搜索引擎排名极为有力!因此,写软文的特别注意,在文章开始的部分尽量加入你需要加入的“文字链”。
(4)网页底部的友情链接是最没有价值的垃圾链接,但有总比没有强(数量原则)。
以上介绍了反向链接的四大原则。链接的合理与丰富是第二位的要素,合理有效的内部链接与丰富的外部链接同等重要,而外部链接中高度相关性高Pr值页面尤为重要。
Haxe和两三年前相比,现在已经很成熟了,很多人都说它的编译器比Flex的还要好,在性能优化、语法上有很多改进。不过并不冲突,可以取长补短。
Haxe的库现在是越来越多,各种引擎、框架、扩展。File Format是一个文件相关的库,用来解析或生成各种文件格式,比如swf、ABC(swf中的字节码)、Flv、Pbj(PixelBender的二进制格式)等等,在作者的TODO列表上,还有一串跟着。
我比较感兴趣的是pdf,编译了一个小小的例子试了下,在解析pdf时碰到了运行时错误。使用反编译器看了下代码,比较多比较乱,看的头昏,希望作者在后续可以完善这个库。
转载:http://www.cnblogs.com/RuiLei/archive/2009/11/25/1610163.html
Google Map应用在网站之上已经从单一的浏览性慢慢转化为服务概念(同时也大大增强用户体验度)
如下利用 Google Map Api —— 简单实现地图网站应用。(仅参考)
实现目标:
1.在地图中进行地点标注
2.选择标注时,出现相关信息
3.点击页面上的测试按钮,显示相关的地点标注信息
Html Code:
<body >
<h1>Google Map</h1>
<div id="Googlemap" style="width: 70%; height: 480px; float: left; border: 1px solid black;">
</div>
<input type="button" id="btnTest" title="test" value="显示第二店信息" />
</body>
前期准备:
<script language="javascript" type="text/javascript" src=http://ditu.google.com/maps?file=api&v=2&key=XXX></script>
如果要实现地点标注,首先要准备数据
数据如下:
var message = [
{ "X": "31.223822", "Y": "121.336311", "Content": { "Title": "别克4s店", "Context": "北翟路1571号"} },
{ "X": "31.175449", "Y": "121.395134", "Content": { "Title": "别克4s店", "Context": "虹梅路1601号"} },
{ "X": "31.095711", "Y": "121.456276", "Content": { "Title": "别克4s店", "Context": "龙吴路"} },
{ "X": "31.078356", "Y": "121.395607", "Content": { "Title": "别克4s店", "Context": "沪闵路"} },
{ "X": "31.200939", "Y": "121.365707", "Content": { "Title": "别克4s店", "Context": "哈密路1231号"} }
];
然后调用
addOverlay(overlay:GOverlay)
将叠加层添加到地图中,并触发 addoverlay
事件。
var point = new GLatLng(X, Y);
var newMkr = GMaps.prototype.CreateMarker(point, i);
map.addOverlay(newMkr);
在标注点上显示相关信息,需要调用openInfoWindowHtml。
openInfoWindowHtml(content:String, opts?:GInfoWindowOptions)
通过标记图标打开地图信息窗口。信息窗口的内容为包含 HTML 文本的字符串。只适用于 GInfoWindowOptions.maxWidth
选项。
实现这点只需要定义一个Trigger即可
GEvent.trigger(XX, "click");
代码解析:(看看注释即可)
var message = [
{ "X": "31.223822", "Y": "121.336311", "Content": { "Title": "别克4s店", "Context": "北翟路1571号"} },
{ "X": "31.175449", "Y": "121.395134", "Content": { "Title": "别克4s店", "Context": "虹梅路1601号"} },
{ "X": "31.095711", "Y": "121.456276", "Content": { "Title": "别克4s店", "Context": "龙吴路"} },
{ "X": "31.078356", "Y": "121.395607", "Content": { "Title": "别克4s店", "Context": "沪闵路"} },
{ "X": "31.200939", "Y": "121.365707", "Content": { "Title": "别克4s店", "Context": "哈密路1231号"} }
];
var GMaps = function() {
};
GMaps.prototype = {
//定义标记容器
makers: [],
//定义鹰眼图标
SetIcon: function(index) {
var markerIcon = new GIcon();
markerIcon.image = "../Images/" + index + ".png";
return markerIcon;
},
//设置地图中心
SetCenter: function(lats, lngs) {
var maxLat = Math.max.apply(null, lats),
maxLng = Math.max.apply(null, lngs),
minLat = Math.min.apply(null, lats),
minLng = Math.min.apply(null, lngs),
lat = minLat + (maxLat - minLat) / 2,
lng = minLng + (maxLng - minLng) / 2,
//定义缩放率
bounds = new GLatLngBounds(new GLatLng(minLat, minLng), new GLatLng(maxLat, maxLng));
map.setCenter(new GLatLng(lat, lng), map.getBoundsZoomLevel(bounds));
},
//定义标记内容
CreateMarker: function(latlng, index) {
if (!latlng) return;
var marker = new GMarker(latlng, { icon: GMaps.prototype.SetIcon(index) });
marker.id = index;
GEvent.addListener(marker, "click", function() {
var myHtml = new Array();
myHtml.push("<span id=\"Info\">");
myHtml.push("<h2>" + message[index].Content.Title + "</h2><br />");
myHtml.push(message[index].Content.Context + "<br />");
myHtml.push("</span>");
map.openInfoWindowHtml(latlng, myHtml.join(''));
});
return marker;
},
//设置触发标记内容显示
TriggerMaker: function(maker) {
GEvent.trigger(maker, "click");
},
//创建地图
BuildMap: function(map) {
//判断当前浏览器是否支持google 地图
if (GBrowserIsCompatible()) {
//定义经纬度容器
var lats = [], lngs = [];
//从地图中删除所有叠加层
map.clearOverlays();
$.each(message, function(i) {
var point = new GLatLng(message[i].X, message[i].Y);
var newMkr = GMaps.prototype.CreateMarker(point, i);
if (newMkr) {
//存储当前Maker到Makers中,用于在地图之外进行选择
GMaps.prototype.makers.push(newMkr);
(function(map, newMkr) {
//将叠加层添加到地图中
map.addOverlay(newMkr);
})(map, newMkr);
}
//存储所有经纬度用于计算当前显示区域
lats.push(message[i].X);
lngs.push(message[i].Y);
});
//设置地图中心区域
GMaps.prototype.SetCenter(lats, lngs);
map.enableDoubleClickZoom();
map.enableScrollWheelZoom();
map.enableContinuousZoom();
map.addControl(new GLargeMapControl())
map.addControl(new GOverviewMapControl());
map.addControl(new GScaleControl());
map.addControl(new GMapTypeControl());
}
else {
alert("No Support Google Map");
}
}
}
最后调用代码:
var map = new GMap2(document.getElementById("Googlemap"));
var mapView = new GMaps();
mapView.BuildMap(map);
$(function() {
$("input[id=btnTest]").click(function() {
mapView.TriggerMaker(mapView.makers[1]);
if (document.documentElement.scrollTop > 250) document.documentElement.scrollTop = 170;
});
});
最终实现效果:
资源:
待续 。。。。有关于Bing Maps的话题
转载:http://www.cnblogs.com/nuaalfm/archive/2009/11/24/1609752.html
filter实际上是一个特性(attribute),它提供了一种向controller 或 action中添加某些任务的方法,当controller 或 action被调用时,会触发filter中定义的相应方法。filter应该算AOP的一种实现方式,关于AOP的内容大家可以参考张逸的文章http://www.cnblogs.com/wayfarer/articles/241024.html,图文并茂对AOP讲解的十分清楚。所以我们就可以在某种程度上利用filter来分解横向和纵向的应用,比方说日志,权限,缓存,防盗链等等应用。
一、我们先来看看ASP.NET MVC 框架提供的几种默认filter类型:
1、Authorize:
准备工作:进入C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727文件夹,双击 aspnet_regSQL.exe选择好相应的数据库,创建membership,AuthorizeAttribute使用membership来进 行权限验证的,所以我们需要先在membership中准备一个用户lfm,一个角色Admin,我们使用studio的项目-》ASP.NET配置创建 即可。
如果lfm不属于Admin角色时Index页是不能访问的
2、OutputCache:
然后我们修改About加入:
<%=DateTime.Now.ToString() %>
我们会发现在一分钟内我们刷新About页面其输出并不改变。这个和webform中的页面缓存机制非常相似。
这里我们也可以统一的配置时间和条件
Controler中输入
3、Exception
标明HandleError属性后的Action,当内部出现异常时会根据异常类型跳转到相应的View,这里需要注意的是上面的源码在开发期无法 看到效果,必须部署到iis上才能看到效果。实际上这个简单处理在项目中用处不大,一般我们都会写自己的异常处理方式,自定义异常处理我们一会再自定义 filter中讲解。
二、自定义filter实例:
我们先来看一下跟filter相关的类结构:
一般情况下我们自定义的filter都是继承FilterAttribute类然后再扩展相应的接口的,下面我们举几个例子:
1、自定义异常处理
使用
浏览器中输入:http://localhost:3983/Home/GetView
这样我们就可以根据自己的项目情况来处理异常了。
2、监控Action运行时间的Timer
使用
页面显示:
<%=ViewData["__Duration"]%>
三、filter相关接口方法的执行顺序:
根据上面的结构图我们知道跟filter相关的总共有四个接口,六个方法,这些方法如果在同一个类中实现时是有个优先级顺序的
IAuthorizationFilter>IActionFilter>IResultFilter>IExceptionFilter
接下来我们写个程序来验证这个顺序:
使用
前端
<%throw new Exception("异常出现"); %>
这时候我们打开c:\test.txt得到的结果为:
OnAuthorization
OnActionExecuting
OnActionExecuted
OnResultExecuting
OnResultExecuted
OnException
四、参考
《Professional ASP.NET MVC 1.0》
http://www.cnblogs.com/leoo2sk/archive/2008/11/05/1326655.html
http://www.cnblogs.com/wayfarer/articles/241024.html
http://www.cnblogs.com/chsword/archive/2009/03/12/zd_mvc6.html
五、源码
我的ASP.NET MVC实践系列
ASP.NET MVC实践系列7-Grid实现(下-利用Contrib实现)
ASP.NET MVC实践系列8-对查询后分页处理的解决方案
其他:
引用thickbox.css样式
引用thickbox.js脚本
动态创建thickbox方法:tb_show(caption, url, imageGroup);
参数说明:
caption:弹出窗口的标题
url:链接地址
imageGroup:图标
页面直接调用方法:
<a href="/info/index?width=240&hieght=300&id=23234" title="标题" class="thickbox">显示窗口</a>
转载:http://www.cnblogs.com/xiaoshatian/archive/2009/11/23/1608432.html
上一篇文章我和大家分享了一些Visual Studio的配色方案,以及一个用来生成配色方案的网页版工具,现在我再来和大家分享一下Visual Studio的字体设置。
字体不仅是设计师手中重要的武器,对我们开发人员来说,字体的选择也有许多讲究,一个好的、适合展示代码的字体,应该具备以下要素:
下图展示了一个极端的反例,虽然很有个性,但并不适合用来显示代码。它的大写字母大的可怕,小写字母却小的可怜;字符不仅不清晰,而且不规范;小写字母l、大写字母I、数字1和符号| 难以分辨;大写字母O和数字0难以分辨;标点符号还凑合,只是下划线为什么是断开的?
当然,这个反例的确有些夸张,但其上文所列举的条件是比较苛刻的,我们在选择字体时没有必要非要完全满足所有条件,事实上这种字体也是凤毛麟角。下文所分享的一些字体也并没有完全满足所有条件,我们发现,只要满足了其中一些关键条件,用来显示代码就已经很不错了。
在Visual Studio中,更改编辑器的字体是件简单的事情,选择菜单【工具】【选项】,在弹出的“选项”对话框中依次选择“环境”和“字体和颜色”,然后在“显示其设置”中选择“文本编辑器”,最后在“字体”中选择字体就可以了,如下图所示:
在上图中,我们发现Visual Studio已经将等宽字体用粗体标识了出来,这样做是为了让我们更容易找到等宽的字体,并不表示等宽字体就一定适合显示代码,比如下图所示的“新宋体”就是一个反例:
在新宋体中,数字0之比大写字母O瘦那么一点点,小写字母l和数字1也十分相像,幸亏配色方案能够颜色将它们区别开来,否则实在难以分辨。这也从另一个角度说明了配色方案与字体是相辅相成的,搭配恰当时,会让代码更加清晰易辨。
下面就和大家分享一些在编程界声名烜赫的字体,截图所采用的配色方案为HumaneStudio,展示顺序为字体首字母升序。这些字体可能乍一看都一样,但仔细品味,还是能够发现不同的味道,希望大家都能找到适合自己的字体。
Andale Mono,演示字号为14,猛击这里下载:
Anonymous Pro,演示字号为14,猛击这里下载:
Bitstream Vera Sans Mono,演示字号为14,猛击这里下载:
Consolas,演示字号为14,Windows或Visual Studio已内置:
Courier New,演示字号为14,Windows已内置:
DejaVu Sans Mono,演示字号为14,猛击这里下载:
Envy Code R,演示字号为16,猛击这里下载:
Inconsolata,演示字号为16,猛击这里下载:
Share TechMono,演示字号为16,猛击这里下载:
注:此字体似乎会将连在一起的fl显示为一个点,不建议使用,可惜可惜。
尾注:本文所分享的字体均支持ClearType。