Chromium文本选择放大镜
2014-05-08 11:04
351 查看
前前后后做了大概两个月,实际时间应该只有一个多月把Chromium的文本选择进行了一系列的优化,包括
1. 文本选择的菜单
2. 文本选择在输入框中的优化,使得在handle移动时,输入框中的内容可以跟着移动。
3. 为文本选择添加放大镜。
关于前两点,基本代码都是JAVA层,内核层也有一些,这次不想多说,有时间把1,2整理一下。
今天主要是想总结一下放大镜的事情。
1. 为什么要做放大镜。
主要是为了能够提高用户的体验,当字体比较小的时候,能够进行准确地选择。
2. 关键点
放大镜的图来自哪里?
关于这个图,我尝试过两种方案,
方案一:是截取当前handle所在的坐标,截取可见区域的网页截图,具体可以
total_scale 是你准备将源可见图放大的倍数。
zoom_rect是想截取的区域(注意这个是未放大的区域)
TransportDIB* transport_dib = NULL;
{
scoped_ptr<skia::PlatformCanvas> canvas(
RenderProcess::current()->GetDrawingCanvas(&transport_dib,
gfx::Rect(canvas_size)));
if (!canvas) {
return;
canvas->scale(total_scale / device_scale_factor_,
total_scale / device_scale_factor_);
canvas->translate(-zoom_rect.x() * device_scale_factor_,
-zoom_rect.y() * device_scale_factor_);
webwidget_->paint(
canvas.get(),
zoom_rect,
WebWidget::ForceSoftwareRenderingAndIgnoreGPUResidentContent);
}
SkBitmap zoom_bitmap;
zoomed_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
zoom_rect.width()*total_scale,
zoom_rect.height()*total_scale);
zoomed_bitmap.setPixels(dib->memory());
//之后注意释放
RenderProcess::current()->ReleaseTransportDIB(transport_dib);
//-------------------------------------------------------------------------------------------------------
这其实有一个问题,就是当Handle在可见区域内,但是handle附近的文本却部分不在可见区域内,这样截取的图必然是不完整的,虽然几率较小,总体上不影响体验,但本着精益求精的精神,又尝试了另一中方案。也就是如下的方案。
方案二:使用FrameView的截图,这样不管索取的截图是否在可见区域内这都不影响,可以截取到FrameView中任意的位置。
FrameView* view = frame()->view();
// 这一句一定得要加上,如果不加可能会导致截图过程中断,导致截取图为空白。
// 因为 ,frame()->view()->paintContents()执行时,如果发现needsLayout, 则返回。
if (view->needsLayout())
view->layout();
PaintBehavior oldBehavior = view->paintBehavior();
view->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
context.save();
context.scale(WebCore::FloatSize(scaleX, scaleY));
context.translate(-x, -y);
IntRect pageRect(x, y, width, height);
context.clip(pageRect);
frame()->view()->paintContents(&context, pageRect);
context.restore();
view->setPaintBehavior(oldBehavior);
然后说一下几个参数:scaleX, scaleY: 是你最终的需要图的宽度,高度
x, y, width, height: 是想要截取的图的坐标。(也就是当前网页中的坐标)
确定方法是:首先确定在选择的文本在所在的frame中的坐标也就是contentsOffset,然后转化成windows, 可以使用函数
zoom_rect = frame->view()->contentsToWindow(baseRect), 得到winowsRect, 注意没有结束,还得继续转化,
WebSize webScrollOffset = mainFrame()->scrollOffset(); (得到mainFrame的scroll
zoom_rect.move(webScrollOffset.width, webScrollOffset.height);
这样就得到了最终所要截取的图的坐标。
当然在做放大镜过程中还有很多的其他点,过程虽然很艰辛,但都一一解决了,这里主要把关键的取图过程和大家分享一下,其实里边还有很过的细节,如TransportDIB的原理,下次认真研究后在分享一下。
1. 文本选择的菜单
2. 文本选择在输入框中的优化,使得在handle移动时,输入框中的内容可以跟着移动。
3. 为文本选择添加放大镜。
关于前两点,基本代码都是JAVA层,内核层也有一些,这次不想多说,有时间把1,2整理一下。
今天主要是想总结一下放大镜的事情。
1. 为什么要做放大镜。
主要是为了能够提高用户的体验,当字体比较小的时候,能够进行准确地选择。
2. 关键点
放大镜的图来自哪里?
关于这个图,我尝试过两种方案,
方案一:是截取当前handle所在的坐标,截取可见区域的网页截图,具体可以
total_scale 是你准备将源可见图放大的倍数。
zoom_rect是想截取的区域(注意这个是未放大的区域)
TransportDIB* transport_dib = NULL;
{
scoped_ptr<skia::PlatformCanvas> canvas(
RenderProcess::current()->GetDrawingCanvas(&transport_dib,
gfx::Rect(canvas_size)));
if (!canvas) {
return;
canvas->scale(total_scale / device_scale_factor_,
total_scale / device_scale_factor_);
canvas->translate(-zoom_rect.x() * device_scale_factor_,
-zoom_rect.y() * device_scale_factor_);
webwidget_->paint(
canvas.get(),
zoom_rect,
WebWidget::ForceSoftwareRenderingAndIgnoreGPUResidentContent);
}
SkBitmap zoom_bitmap;
zoomed_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
zoom_rect.width()*total_scale,
zoom_rect.height()*total_scale);
zoomed_bitmap.setPixels(dib->memory());
//之后注意释放
RenderProcess::current()->ReleaseTransportDIB(transport_dib);
//-------------------------------------------------------------------------------------------------------
这其实有一个问题,就是当Handle在可见区域内,但是handle附近的文本却部分不在可见区域内,这样截取的图必然是不完整的,虽然几率较小,总体上不影响体验,但本着精益求精的精神,又尝试了另一中方案。也就是如下的方案。
方案二:使用FrameView的截图,这样不管索取的截图是否在可见区域内这都不影响,可以截取到FrameView中任意的位置。
FrameView* view = frame()->view();
// 这一句一定得要加上,如果不加可能会导致截图过程中断,导致截取图为空白。
// 因为 ,frame()->view()->paintContents()执行时,如果发现needsLayout, 则返回。
if (view->needsLayout())
view->layout();
PaintBehavior oldBehavior = view->paintBehavior();
view->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
context.save();
context.scale(WebCore::FloatSize(scaleX, scaleY));
context.translate(-x, -y);
IntRect pageRect(x, y, width, height);
context.clip(pageRect);
frame()->view()->paintContents(&context, pageRect);
context.restore();
view->setPaintBehavior(oldBehavior);
然后说一下几个参数:scaleX, scaleY: 是你最终的需要图的宽度,高度
x, y, width, height: 是想要截取的图的坐标。(也就是当前网页中的坐标)
确定方法是:首先确定在选择的文本在所在的frame中的坐标也就是contentsOffset,然后转化成windows, 可以使用函数
zoom_rect = frame->view()->contentsToWindow(baseRect), 得到winowsRect, 注意没有结束,还得继续转化,
WebSize webScrollOffset = mainFrame()->scrollOffset(); (得到mainFrame的scroll
zoom_rect.move(webScrollOffset.width, webScrollOffset.height);
这样就得到了最终所要截取的图的坐标。
当然在做放大镜过程中还有很多的其他点,过程虽然很艰辛,但都一一解决了,这里主要把关键的取图过程和大家分享一下,其实里边还有很过的细节,如TransportDIB的原理,下次认真研究后在分享一下。
相关文章推荐
- 选择文本ff/ie
- Ext Js 3.2修改文本颜色和在表格中插入图片,主要是性别进行判断来选择图片
- 文本分类特征选择方法——卡方检验信息增益
- vim中对文本的选择
- android webview页面中的文件(apk,mp3或mp4,以及文本等)链接,选择被打开还是直接下载
- 文本特征选择之互信息和卡方
- 文本选择
- 如何在 Vim 中进行文本选择操作和使用标志
- jQuery取得select选择的文本与值
- JQuery 增加、删除表格div层文本内容的JS代码 和仿select个性下拉框选择效果JS代码
- 禁止右键+禁止选择文本JS代码分享(兼容主流浏览器)
- jquery操作checkbox方法(全选、全不选、至少选择一个、选择值/文本)
- 文本协议与二进制协议的选择
- JS实现兼容各种浏览器的获取选择文本的方法【测试可用】
- 《屏幕上的聪明决策》:4星。人类在手机/电脑上做选择的心理学研究的综述。不流畅的文本有助于理解和记忆,淘汰赛制可以有效降低选择后懊悔。
- 不同文本模型的选择之ROC曲线
- 以字段选择排序 --shell笔记(文本排序)
- 机器学习:文本挖掘之特征选择
- winform在richTextBox中查找并选择指定的文本
- JQuery禁用右键、文本选择功能、复制按键的实现(转载)