R 初始化图形设备时,如何设置设备复制参数?
我正在使用R软件包中的图形设备,需要设置一些 初始化或重置设备上的文本/标签的图形参数 该特性在R内部构件中描述: GPar结构的三个副本用于存储当前参数(通过gpptr访问), “设备副本”(通过dpptr访问)和“设备副本”参数保存副本的空间。 当前参数显然是当前正在使用的参数,并且是从“设备副本”复制的 每当调用plot.new()时(无论是否进入下一个“页面”)。保存的副本 保持上次完全清除设备时的状态(例如,调用plot.new()时) 使用par(new=TRUE)),并用于重播显示列表 如何从包中实际访问和初始化“设备副本” 我所能找到的只是一条评论,里面有一个更老的, 将粘贴的注释复制到R 初始化图形设备时,如何设置设备复制参数?,r,R,我正在使用R软件包中的图形设备,需要设置一些 初始化或重置设备上的文本/标签的图形参数 该特性在R内部构件中描述: GPar结构的三个副本用于存储当前参数(通过gpptr访问), “设备副本”(通过dpptr访问)和“设备副本”参数保存副本的空间。 当前参数显然是当前正在使用的参数,并且是从“设备副本”复制的 每当调用plot.new()时(无论是否进入下一个“页面”)。保存的副本 保持上次完全清除设备时的状态(例如,调用plot.new()时) 使用par(new=TRUE)),并用于重播显示
GraphicsDevice.h
:
* 2. I found this comment in the doc for dev_Open -- looks nasty
* Any known instances of such a thing happening? Should be
* replaced by a function to query the device for preferred gpars
* settings? (to be called when the device is initialised)
*
* NOTE that it is perfectly acceptable for this
* function to set generic graphics parameters too
* (i.e., override the generic parameter settings
* which GInit sets up) all at the author's own risk
* of course :)
我不知道我是否完全理解你的意图,但我认为你可能会发现这很有用。一些关键摘录: 要创建具有自己功能的运行图形设备,我们调用 graphicsDevice()函数。虽然有几种方法 本质上,我们给它一个指定 部分或全部21个图形原语的实现 操作。我们可以将其作为一个列表或一个 RDEVDESC方法或我们为特定类型定义的子类的 这个装置。所以我们专注于编写这些函数 然后: 每个方法都传递一个类为DevDescPtr的对象。这是 也是顶级函数返回的值的类型 graphicsDevice()。这是一个参考C级数据结构 表示图形设备。我们可以使用它来查询设置 图形设备的 使用设备中的某些字段 在初始化设备时,而不是在功能内(例如。 名称前缀为“开始”的人)。其他领域包括 有关渲染图形不同方面的结构信息 装置。例如,我们可以找到绘图区域的尺寸, DevDescPtr类本质上是R中的不透明数据类型 (包含指向C级数据结构的外部指针)并且 旨在将其用作R级列表。我们可以使用$ 运算符访问各个字段,我们可以找到 这些字段的名称为() 最后: 在某些罕见的情况下,转换 对R对象的引用。我们可以通过把它强迫给 名为DevDesc的相应R类(即带有“Ptr”移除),即。 as(dev,“DevDesc”)。这将复制C级中的每个字段 结构到R类中相应的插槽 例如,设备的
circle
方法具有以下签名:
circle ( numeric, numeric, numeric, R_GE_gcontextPtr, DevDescPtr )
R_GE_gcontextPtr是:
…对C级数据类型实例的另一个引用。这是
有关设备“当前”设置的信息。这给了我们
有关当前笔/前景色、背景的信息
颜色、gamma级别设置、线宽、样式、连接、,
字符点大小和扩展/放大率,以及字体
信息。可用字段为
警告
我将在这里提出一个主要使用C++代码的解决方案。为了使它更具可复制性,以便可以在R控制台中运行,我使用
Rcpp::cppFunction
完成了这项工作。但是,这显然不是构建包时使用的方法。生成的函数通过访问用户必须指定的R图形设备的原始指针来工作,如果使用不存在的设备号调用它们,则R会话将崩溃
解决方案 这些注释所描述的
GPar
结构的三个副本保存在另一个名为baseSystemState
的结构中,该结构已定义
每个图形设备都有一个指针指向<代码> BaseSistMSTATE < /C>,如果我们在我们自己的代码中包含头文件<代码>包含/RXEX/GracixsEng.H./Cuth>,我们可以使用C或C++代码访问图形设备。 然而,有一个障碍。虽然我们可以获得指向
baseSystemState
结构的指针,但我们的代码不知道这实际上是什么,因为baseSystemState
和GPar
的定义不属于公共API
因此,为了阅读它所包含的baseSystemState
和GPar
s,我们必须在我们自己的代码中重新定义这些结构(正如德克在评论中所建议的)。GPar
的某些成员也是需要首先定义的类型或枚举
我们可以将这些定义压缩成一个字符串,并将它们用作Rcpp::cppFunction
调用中的includes
。这里有一个包装器函数,它允许您编写C++函数,这些函数可以访问现有的图形设备参数:
cppFunction\u图形dp
到GPar GP=bss->GP
或GPar GP=bss->dpSaved
更多的是一个R-devel或R-package-devel问题,而不是Rcpp可以帮助的问题,不是吗?我已经在R-package-devel上问过了,一周后没有得到任何回复,所以我在这里再试一次。如果再过一周仍然没有线索,我可能会增加一笔赏金。@NealFultz你能详细说明一下你想要实现的目标吗?当用户打开新的图形设备时,您是否正在尝试检查设备功能、尺寸等?您是否正在尝试检查和设置未在par
中列出的图形参数?如果有,哪些?对graphics
和grDevices
后面的C代码进行一些低级调用相当容易,
names(new("R_GE_gcontextPtr"))
[1] "col" "fill" "gamma" "lwd" "lty"
[6] "lend" "ljoin" "lmitre" "cex" "ps"
[11] "lineheight" "fontface" "fontfamily"
cppFunction_graphics("
Rcpp::List get_default_GPar(int devnum)
{
pGEDevDesc dd = GEgetDevice(devnum);
baseSystemState *bss = (baseSystemState*) dd->gesd[0]->systemSpecific;
GPar GP = bss->dp;
auto get_colour = [](rcolor rcol){
return Rcpp::NumericVector::create(
Rcpp::Named(\"red\") = rcol & 0xff,
Rcpp::Named(\"green\") = (rcol >> 8) & 0xff,
Rcpp::Named(\"blue\") = (rcol >> 16) & 0xff);
};
return Rcpp::List::create(Rcpp::Named(\"fg\") = get_colour(GP.fg),
Rcpp::Named(\"bg\") = get_colour(GP.bg),
Rcpp::Named(\"col\") = get_colour(GP.col),
Rcpp::Named(\"colmain\") = get_colour(GP.colmain),
Rcpp::Named(\"collab\") = get_colour(GP.collab),
Rcpp::Named(\"colaxis\") = get_colour(GP.colaxis));
}
")
plot(1:10)
get_default_GPar(dev.cur() - 1)
#> $fg
#> red green blue
#> 0 0 0
#>
#> $bg
#> red green blue
#> 255 255 255
#>
#> $col
#> red green blue
#> 0 0 0
#>
#> $colmain
#> red green blue
#> 0 0 0
#>
#> $collab
#> red green blue
#> 0 0 0
#>
#> $colaxis
#> red green blue
#> 0 0 0
cppFunction_graphics("
void set_col(int dn, int red, int green, int blue, int alpha)
{
int new_col = red | (green << 8) | (blue << 16) | (alpha << 24);
pGEDevDesc dd = GEgetDevice(dn);
baseSystemState *bss = (baseSystemState*) dd->gesd[0]->systemSpecific;
bss->dp.collab = new_col;
}
")
set_col(dev.cur() - 1, 255, 0, 0, 255)
plot(1:10)